C++运算符重载:没有从对象到引用的已知转换?

DrG*_*erm 13 c++ operator-overloading

当我尝试编译以下内容时(g ++ 4.6.3)

class A {};

A& operator*=( A& a, const A& b )
{
  return a;
}

A operator*( const A& a, const A& b )
{
  return A( a ) *= b;
}

int main( int, char*[] )
{
  A a, b;

  a = a*b;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我收到了错误

/tmp/test.cxx: In function ‘A operator*(const A&, const A&)’:
/tmp/test.cxx:14:20: error: no match for ‘operator*=’ in ‘(* & a) *= b’
/tmp/test.cxx:14:20: note: candidate is:
/tmp/test.cxx:6:1: note: A& operator*=(A&, const A&)
/tmp/test.cxx:6:1: note:   no known conversion for argument 1 from ‘A’ to ‘A&’
Run Code Online (Sandbox Code Playgroud)

这让我很困惑 - 如何才能知道从一个类转换到该类的引用?

如下更改A类声明没有任何效果:

class A
{
public:
  A() {}
  A( const A& ) {}
};
Run Code Online (Sandbox Code Playgroud)

同样的错误.

我会非常感谢这里发生了什么.

Kon*_*lph 13

像Lucian所说,你不能将临时对象绑定到非const引用.编译器的期望是对象在表达式之后将不再存在,因此修改它是没有意义的.

要修复你的代码,删除临时(使参数const&没有意义operator *=):

A operator*(A a, const A& b)
{
    return a *= b;
}
Run Code Online (Sandbox Code Playgroud)


cra*_*jul 5

在编写时A( a ),可以创建一个复制构造的类型A(右值)的临时值a.C++声明没有rvalue可以作为非const引用传递.Visual Studio对此规则有点草率,但gcc等强制执行它.

要修复,请尝试此操作(这完全相同,但您可以通过命名该变量来创建左值).更多关于l-和r-值的信息

A operator*( A a, const A& b )
{
   return a *= b;
}
Run Code Online (Sandbox Code Playgroud)

  • 与我在Konrad的回答中发布的相同的反对意见. (2认同)