为什么链接要求操作员返回参考?

yan*_*pas 1 c++ operator-overloading

应该返回参考的最受欢迎的运算符是 operator=

class Alpha
{
    int x;
    int y;
    std::string z;
  public:
    void print()
        { cout << "x " << x << " y " << y << "  " << z << '\n'; }
    Alpha(int xx=0, int yy=0, std::string zz=""): x(xx), y(yy), z(zz) {}
    Alpha operator=(Alpha& another)
    {
        x = another.x;
        y = another.y;
        z = another.z;
        return *this;
    }


};

int main()
{
    Alpha a(3,4,"abc"),b,c;
    b=c=a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Clang说:

clang ++ - 3.6 new.cxx -o new new.cxx:70:3:错误:没有可行的重载'='b = c = a; 〜^ ~~~ new.cxx:34:8:注意:候选函数不可行:期望第一个参数的一个l值Alpha运算符=(Alpha&另一个)生成^ 1错误.

gcc这个:

new.cxx:34:8:注意:参数1从'Alpha'到'Alpha&'没有已知的转换

但我无法理解理论上的问题是什么.我认为发生了什么:

  1. 首先,对象调用operator = c.它a通过引用接收对象,将其值复制到c并返回它的self(对象c)的匿名副本:调用复制soncstructor.
  2. 然后调用operator = for object b.它需要rvalue ref,但我们只写了左值引用,因此发生错误.

我已经加入RVAL运算符=和拷贝构造函数,它接收左值参考,一切工作,现在我不知道为什么(我应该写哪个接收右值的拷贝构造函数const Alpha& sAlpha&& s):

class Alpha
{
    int x;
    int y;
    std::string z;
  public:
    void print()
    { cout << "x " << x << " y " << y << "  " << z << '\n'; }
    Alpha(int xx=0, int yy=0, std::string zz=""): x(xx), y(yy), z(zz) {}
    //Alpha(Alpha&& s): x(s.x), y(s.y), z(s.z) {}
    Alpha(Alpha&& ) = delete;
    Alpha(Alpha& s): x(s.x), y(s.y), z(s.z) {}
    Alpha operator=(Alpha& another)
    {
        x = another.x;
        y = another.y;
        z = another.z;
        return *this;
    }
    Alpha operator=(Alpha&& another)
    {
        x = another.x;
        y = another.y;
        z = another.z;
        return *this;
    }

};
Run Code Online (Sandbox Code Playgroud)

Bo *_*son 7

赋值运算符的此签名

Alpha operator=(Alpha& another)
Run Code Online (Sandbox Code Playgroud)

两个方面是不寻常的.第一个是它返回指定对象的副本.很少这样做.另一个是它接受非const引用作为参数.

非const引用使它不接受临时对象作为参数(因为它们只会绑定到const lvalue引用).

在组合中,这意味着从第一个返回的临时operator=值不能用作第二个的参数operator=.

您可以选择返回引用或创建参数Alpha const&.两种选择都可以单独使用,也可以组合使用.

正如您所发现的,第三个选项是显式添加移动赋值运算符,使用Alpha&&它专门接受临时值.

标准方法是声明复制赋值运算符

Alpha& operator=(Alpha const& other);
Run Code Online (Sandbox Code Playgroud)

除非您有非常具体的理由选择其他签名.