我成功为名为全局的全局范围内的模板类构建了一个重载运算符+(全局左, int 右)。
template <typename T>
class Global {
public:
Global operator+(const int& right) const
{
cout << "Using Global overloaded operator+" << endl;
return *this;
}
};
由于加法是可交换的,我还创建了另一个重载运算符+( int 左,全局右)以允许可换行操作。
template <typename T>
Global<T> operator +(int left, Global<T> right)
{
return right + left;
}
这是我尝试为嵌套类做同样的事情。
template <typename T>
class Container {
public:
class Nested {
public:
Nested operator+(const int& right) const
{
cout << "Using Nested overloaded operator+" << endl;
return *this;
}
};
};
template <typename T> // The following line is critical
typename Container<T>::Nested operator+(int left, typename Container<T>::Nested right)
{// Both 'typename' are necessary to avoid extra compilation errors
return right + left;
}
现在,当我尝试执行以下代码来测试运算符重载时,在尝试使用嵌套类中的commutable operator +时出现了一些编译错误,主要是“错误C2783 - 'Container :: Nested operator + (int,Container :: Nested)':无法推断'T'的模板参数“,但”错误E0349 - 没有运算符“+”匹配这些操作数“。
int main(void)
{
Global<int> global;
global + 2; // Works perfectly
2 + global; // Works perfectly
Container<int>::Nested nested;
nested + 2; // Works perfectly
2 + nested; // Compilation Error C2783 and E0349
system("pause"); // Everything works fine without the line above
return 0;
}
我在启用 / std:c ++最新的情况下使用Visual Studio 15.5.2。如果可能的话,我希望在嵌套类定义中定义operator +。
答案 0 :(得分:2)
如this answer所示,在这种情况下,模板推导要比人们想象的要复杂得多。要解决此问题,您可以在friend
类中将该函数声明为Nested
,如下所示:
template <typename T>
class Container {
public:
class Nested {
public:
Nested operator+(const int& right) const
{
std::cout << "Using Nested overloaded operator+" << std::endl;
return *this;
}
// moved here and declared as friend, instead of declaring it somewhere else
friend Nested operator+(int left, Nested right)
{
return right + left;
}
};
};
通过这样做,您还可以避免在签名中使用双typename
和Container<T>::
(感谢@ Jarod42 )。