【问题标题】:How to write a commutable overloaded arithmetic operator for a template nested class?如何为模板嵌套类编写可交换的重载算术运算符?
【发布时间】:2018-01-12 01:40:06
【问题描述】:

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

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

        return *this;
    }
};

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

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

现在,当我尝试执行以下代码来测试运算符重载时,在尝试使用嵌套类中的可交换运算符 + 时遇到一些编译错误,主要是 "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+。

【问题讨论】:

  • Global&lt;T&gt; operator +(int left, typename Global&lt;T&gt; right) 应该是 Global&lt;T&gt; operator +(int left, Global&lt;T&gt; right)。那里不需要typename
  • 全局运算符+ 完全没问题。如果您指的是嵌套运算符+,我尝试将类型名删除为“Container::Nested operator+(int count, Container::Nested iterator)”。编译器会抛出很多与 operator+ 无关的额外错误,例如 Error C2065 'global': undeclared identifier。如果我只删除一个“类型名”,也会发生同样的情况。
  • Global&lt;T&gt; operator + 中使用typename,我的编译器给出了不必要的typename 错误...
  • 如果我理解正确的话,我尝试将这一行typename Container&lt;T&gt;::Nested operator+(int left, typename Container&lt;T&gt;::Nested right) 切换成这行Container&lt;T&gt;::Nested operator+(int left, typename Container&lt;T&gt;::Nested right)
  • 那你误会了。我复制粘贴了您发布的确切代码。我的意思是删除 second 代码块中提供的函数中的typename,即:Global&lt;T&gt; operator +(int left, typename Global&lt;T&gt; right)typename 这里是错误的

标签: c++ templates nested operator-overloading


【解决方案1】:

正如this answer 中所见,在这种情况下,模板推导比人们想象的要复杂得多。要解决此问题,您可以在 Nested 类中将函数声明为 friend,如下所示:

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&lt;T&gt;::感谢 @Jarod42)。

【讨论】:

  • 我知道 Global 类中多余的 typename 是不必要的,让我们从问题中删除它,因为它与它无关。感谢您提供快速、格式正确且正确的答案。
  • @user2565020 同意,我删除了有关它的部分。总是乐于提供帮助
猜你喜欢
  • 2013-09-20
  • 1970-01-01
  • 1970-01-01
  • 2017-10-29
  • 2018-06-28
  • 2011-11-15
  • 2021-10-19
  • 2014-10-15
  • 1970-01-01
相关资源
最近更新 更多