【问题标题】:No implicit conversion in overloaded operator重载运算符中没有隐式转换
【发布时间】:2010-11-12 13:27:51
【问题描述】:

d1 + 4 有效,但 4 + d1 无效,即使 4 可以隐式转换为 GMan。为什么它们不相等?

struct GMan
{
    int a, b;

    GMan() : a(), b() {}
    GMan(int _a) : a(_a), b() {}
    GMan(int _a, int _b) : a(_a), b(_b) {}

    GMan operator +(const GMan& _b)
    {
         GMan d;
         d.a = this->a + _b.a;
         d.b = this->b + _b.b;
         return d;
    }
};

int main()
{
    GMan d1(1, 2), d(2);
    GMan d3;
    d3 = d1 + 4; 
    d3 = 4 + d1;
}

【问题讨论】:

  • 你试过问GMan吗?
  • @GMan 的粉丝?惊人的。我的粉丝(如果有的话)在哪里? :P
  • 我认为其中一个 GMan 应该是明确的 :)
  • 我喜欢这个问题。
  • @GMan 大声笑我对更改名称的限制一无所知。这是史诗般的失败 xD

标签: c++ operator-overloading implicit-conversion


【解决方案1】:

C++ 编译器将调用x + y 转换为以下两个调用之一(取决于x 是否属于类类型,以及是否存在这样的函数):

  1. 会员功能

    x.operator +(y);
    
  2. 免费功能

    operator +(x, y);
    

现在 C++ 有一个简单的规则:在成员访问运算符 (.) 之前不能发生隐式转换。这样,上述代码中的x 不能在第一个代码中进行隐式转换,但在第二个代码中可以。

这条规则是有道理的:如果x 可以在上面的第一个代码中隐式转换,C++ 编译器将不再知道要调用哪个函数(即它属于哪个类),所以它必须搜索 所有现有类用于匹配的成员函数。这将对 C++ 的类型系统造成严重破坏,并使重载规则更加复杂和混乱。

【讨论】:

    【解决方案2】:

    This 答案是正确的。然后,这些要点需要实现此类运算符的规范方式:

    struct GMan
    {
        int a, b;
    
        /* Side-note: these could be combined:
        GMan():a(),b(){}
        GMan(int _a):a(_a),b(){}
        GMan(int _a, int _b):a(_a),b(_b){}
        */
        GMan(int _a = 0, int _b = 0) : a(_a), b(_b){} // into this
    
        // first implement the mutating operator
        GMan& operator+=(const GMan& _b)
        {
            // the use of 'this' to access members
            // is generally seen as noise
            a += _b.a;
            b += _b.b;
    
            return *this;
        }
    };
    
    // then use it to implement the non-mutating operator, as a free-function
    // (always prefer free-functions over member-functions, for various reasons)
    GMan operator+(GMan _a, const GMan& _b)
    {
        _a += b; // code re-use
        return _a;
    }
    

    其他运营商依此类推。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-09
      • 2014-08-18
      • 1970-01-01
      • 2013-04-29
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多