【问题标题】:Define friend user defined literal operator inside the class在类中定义朋友用户定义的文字运算符
【发布时间】:2016-05-19 15:56:33
【问题描述】:

为什么要在 give error 类中定义用户定义的文字?

class test
{
    long double x;
    public:    
    friend test operator""_UNIT(long double v)
    {
        test t;
        t.x = v;
        return t;
    }       
};

int main()
{
    test T = 10.0_UNIT;        
    return 0;
}

错误:

unable to find numeric literal operator 'operator""_UNIT'

注意:可以在类中定义any friend function

class test
{
    int x;
    public:
    test():x(10) {}
    friend std::ostream& operator<< (std::ostream& o, test t)
    {
        o << t.x ;
        return o;
    }
};

int main() {
    test T;
    std::cout << T;
    return 0;
}

同一个朋友用户定义的文字可以定义为outside the class

class test
{
    long double x;
    public:    
    friend test operator""_UNIT(long double v);
};

test operator""_UNIT(long double v)
{
    test t;
    t.x = v;
    return t;
}

int main()
{
    test T = 10.0_UNIT;        
    return 0;
}

标准中的这句话有影响吗?

类中定义的友元函数在 定义它的类。在外部定义的友元函数 类不是

【问题讨论】:

  • 当您从main() 执行operator&lt;&lt;(std::ostream&amp;, test) 时,它必须查找函数并在test 中查找,因为它是参数之一。 _UNIT 的唯一位置是在当前空间中,而 _UNIT 不存在。
  • 关键区别在于operator&lt;&lt; 具有扩展查找的参数类型,但_UNIT 没有

标签: c++ c++11


【解决方案1】:

您遇到的问题是,来自 [namespace.memdef]:

朋友声明不被 本身使名称对非限定查找 (3.4.1) 或限定查找 (3.4.3) 可见。

找到它们的方法是通过参数依赖查找,[basic.lookup.argdep]:

在考虑关联的命名空间时,查找与执行的查找相同 关联命名空间用作限定符(3.4.3.2),除了: [...] 关联类中声明的任何命名空间范围的友元函数或友元函数模板都是 在它们各自的命名空间中可见,即使它们在普通查找期间不可见 (11.3)。

std::ostream&amp; operator&lt;&lt; (std::ostream&amp; o, test t) 是由于对第二个参数的依赖于参数的查找而找到的。

当您在类中定义_UNIT 外部 时,它使函数可见。

但是,当您定义 _UNIT 内联时 - 它对正常查找不可见,并且唯一的参数 (double) 没有任何关联的命名空间,因此也无法通过依赖于参数的查找找到它。

【讨论】:

  • 那我该如何避免呢?
  • @KhiemGOM 只是不要以不起作用的方式定义它?
  • 你能给出一个有效的文字定义的代码示例吗?还有为什么在与 main 相同的文件中定义它会使其运行良好,但是当我在单独的 .cpp 文件中定义它时,它不起作用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
  • 2014-10-08
相关资源
最近更新 更多