【问题标题】:Commutative operator + overloading causes infinite recursion交换运算符 + 重载导致无限递归
【发布时间】:2020-05-30 08:06:09
【问题描述】:
#include <iostream>
using namespace std;

class StringNum {
public:
    string s;
    StringNum() {s = "";}
public:
    StringNum(int n) {
        s = "";
        for (int i=1; i<=n; i++) s += "x";
    }

    operator int () {
        return s.length();
    }

    StringNum operator + (StringNum v) {
        cout << "operator + is called\n";
        int len = s.length() + v.s.length();
        StringNum res;
        for (int i=1;i<=len;i++) res.s += "x";
        return res;
    }

    template <class T>
    StringNum operator + (T value) {
        return (*this) + StringNum(value);
    }
};

template<class T>
StringNum operator + (T value, const StringNum& num) {
    cout << "operator + opposite is called\n";
    //return value + num; // infinite recursion, of course
    // return num + value;  // infinite recursion, despite StringNum + <class T> is defined
    return num + StringNum(value); // STILL infinite recursion
    //return StringNum(num) + value; // correct, output 6
}

int main()
{
    StringNum x(4);
    cout << (x + 2.5) << "\n"; // StringNum + <class T>, output 6
    int res = (2 + x);
    cout << res;
    return 0;
}

StringNum 类表示大于 0 的整数,其中字符串的长度为数字。

StringNum + StringNum 是成员函数并且可以正常工作。

StringNum + &lt;class T&gt; 也是一个成员函数,可以正常工作。

但是,对于&lt;class T&gt; + StringNum,它需要一个外部函数。但是,operator + 的行为令人困惑,没有任何意义:

template<class T>
StringNum operator + (T value, const StringNum& num) {
    cout << "operator + opposite is called\n";
    //return value + num; // infinite recursion, of course
    // return num + value;  // StringNum + <class T>, infinite recursion. Why??
    return num + StringNum(value); // STILL infinite recursion
    //return StringNum(num) + value; // StringNum + <class T> -> this time it's correct, output 6
}

num + StringNum(value) 如何导致无限递归,而它应该调用 StringNum + StringNum ?另外,为什么 num + value 会导致无限递归,而它应该调用 StringNum + &lt;class T&gt; ?最后,当num首先是StringNum时,StringNum(num) + value如何解决问题?

在这种情况下,我怎样才能正确实现commutative operator +?谢谢。

【问题讨论】:

  • 尝试将StringNum operator+(const StringNum&amp; op1, const StringNum&amp; op2) 作为非成员函数。见stackoverflow.com/q/4622330/10077
  • s = ""; for (int i=1; i&lt;=n; i++) s += "x"; 可以替换为s = std::string(n, 'x');

标签: c++ class templates type-conversion operator-overloading


【解决方案1】:

使用正确的常量:

StringNum operator + (const StringNum& v) const {
    cout << "operator + is called\n";
    int len = s.length() + v.s.length();
    StringNum res;
    for (int i=1;i<=len;i++) res.s += "x";
    return res;
}

template <class T>
StringNum operator + (T value) const {
    return (*this) + StringNum(value);
}

Demo

在您的模板中,

你用const StringNum&amp;StringNum打电话给operator+

候选人是:

  • StringNum StringNum::operator + (StringNum v) 不匹配,仅适用于非 const lhs
  • template &lt;class T&gt; StringNum StringNum::operator + (T value) 不匹配,同上原因
  • template&lt;class T&gt; StringNum operator + (T value, const StringNum&amp; num) 匹配,所以导致无限递归。

【讨论】:

  • 你的意思是 operator 的结果应该总是 const 吗?编辑:我的意思是最后的 const 关键字。
  • @HuyĐứcLê 你的意思是 operator 的结果应该总是 const 吗? -- 你指的是哪个const?该参数应该作为const 引用传递,并且由于+ 函数不会改变StringNum 的任何成员,因此应将其标记为const 函数。
  • 我的意思是“不会改变任何成员”常量。但是你能解释一下如何解决无限递归(调用错误的运算符)问题吗?
  • @HuyĐứcLê 您的全局运算符+函数采用 const StringNum 参数。您不能使用 const 类变量调用非常量成员函数。所以成员 operator+ 函数不符合条件
  • 哦。我现在记得。谢谢。
猜你喜欢
  • 2018-11-08
  • 1970-01-01
  • 2023-03-17
  • 2011-01-22
  • 1970-01-01
  • 2015-08-30
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
相关资源
最近更新 更多