c++ - 为什么我不能定义一个一元运算符,然后在 MSVC 的模板类中声明一个同名的友元二元运算符?

标签 c++ templates visual-c++ operator-overloading friend

考虑这样的代码:

template<typename S>
class C;

template<typename S>
C<S> operator-(C<S> lhs, C<S> rhs);

template<typename S>
class C
{
public:
    C operator-() { return *this; }
    friend C operator-<S>(C lhs, C rhs);//error on this line
};

template<typename S>
C<S> operator-(C<S> lhs, C<S> rhs) { return C<S>(); }

int main(int argc, char** argv)
{
    C<int> a,b;
    a-b;
    return 0;
}

这给了我 MSVC 中的 6 个错误。但是,如果我在友元声明之后移动 C operator-() 的定义,它就会编译。如果我将类更改为未模板化的类,它会编译。这似乎也在 g++ 中编译。 (我没有安装 g++,基于 https://wandbox.org/ )

那么这里有什么问题呢?

最佳答案

我找到了一些有用的信息数据here .问题在于成员运算符一元减法隐藏了全局二元减法。所以我必须声明 friend

friend C<S> (::operator-<S>)(C<S> lhs, C<S> rhs);

在全局范围内明确要求运算符-:在 C++ 中,名称查找发生在类型检查之前。

此外,由于 friend 不是类的一部分(我想这就是原因),必须在返回类型和参数类型之后写模板参数。没有它们(即 friend C (::operator-<S>)(C lhs, C rhs); )它仍然可以在 MSVC 中工作,但不能用于 g++。

关于c++ - 为什么我不能定义一个一元运算符,然后在 MSVC 的模板类中声明一个同名的友元二元运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57911295/

相关文章:

javascript - 通过 Polymer 中的内容标签访问轻型 DOM

c++ - 是否可以在模板中定义指向外部 -"C"函数类型的指针?

c++ - 矩阵模板加法运算符重载

c++ - MFC CEdit 将非ascii字符转换为ascii

c++ - 为什么 visual studio 2015 只允许我使用 1 个核心的 50%?

c++ - 为初学者澄清 C++ 中类定义和实现的一些细节

c++ - static_cast<Derived *>(Base pointer) 是否应该给出编译时错误?

C++ 模板和 STL vector 问题

c++ - 如何使用 MFC 或 C++ 增加或减少系统时间?

c++ - 如何防止 VC++ 9 链接器链接不必要的全局变量?