当我尝试编译以下内容时(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;
}
我收到错误
/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&’
这让我很困惑 - 如何才能知道从一个类到该类的引用的转换?
如下更改A类声明没有任何效果:
class A
{
public:
A() {}
A( const A& ) {}
};
同样的错误。
我非常感谢这里发生了什么。
答案 0 :(得分:13)
就像Lucian所说,你不能将临时对象绑定到非const引用。编译器的期望是对象在表达式之后将不复存在,因此修改它是没有意义的。
要修复代码,请删除临时代码(使const&
中的参数operator *=
无效):
A operator*(A a, const A& b)
{
return a *= b;
}
答案 1 :(得分:5)
当您编写A( a )
时,您创建了一个临时的A类型(右值),您可以使用a
进行复制。 C ++声明没有rvalue可以作为非const引用传递。 Visual Studio对这个规则有点草率,但gcc等强制执行它。
要修复,请尝试此操作(完全相同,但您可以通过命名该变量来创建左值)。更多关于l-和r-值here
A operator*( A a, const A& b )
{
return a *= b;
}