c++ - 如何为模板嵌套类编写可交换的重载算术运算符?

标签 c++ templates nested operator-overloading

我成功地为名为 Global 的全局范围内的模板类构建了重载运算符 +(Global 左侧,int 右侧)。

template <typename T>
class Global {
public:
    Global operator+(const int& right) const
    {
        cout << "Using Global overloaded operator+" << endl;

        return *this;
    }
};

由于加法是可交换的,我还创建了另一个重载运算符 +(int 左侧,Global 右侧)以允许可交换操作。

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;
}

现在,当我尝试执行以下代码来测试运算符重载时,在尝试使用 Nested 类中的可交换运算符 + 时出现一些编译错误,主要是 "Error C2783 - 'Container::Nested operator + (int,Container::Nested)':无法推断出“T”的模板参数”,而且“错误 E0349 - 没有运算符“+”匹配这些操作数”。。 p>

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++latest 的 Visual Studio 15.5.2。如果可能,我希望在嵌套类定义中定义 operator+。

最佳答案

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;
        }
    };
};

通过这样做,您还可以避免使用双 typenameContainer<T>:: (感谢@Jarod42)在签名中。

关于c++ - 如何为模板嵌套类编写可交换的重载算术运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48218385/

相关文章:

C++ Runtime类切换,依赖基类继承

c++ - 这种错误记录方案有什么问题吗?

c++ - 在 C++ 中查找一组结构

c++ - 为什么编译器不给出不明确的引用错误?

c++ - 编译时等效的 std::cout,或 c++11 中编译时常量值的 static_assert 字符串化

c++ - 如何调用模板类的模板构造函数?

c++ - 无法从模板基类导入 typedef

ruby-on-rails - rails accepts_nested_attributes_for :reject_if not working

r - 嵌套函数是否更慢?

python - 在 Python 中解包嵌套的 C 结构