13

当我尝试编译以下(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& ) {}
};

同样的错误。

我将非常感谢有关这里发生的事情的提示。

4

2 回答 2

13

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

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

A operator*(A a, const A& b)
{
    return a *= b;
}
于 2012-04-19T20:35:20.120 回答
5

当您编写时A( a ),您会创建一个 A 类型的临时变量(一个右值),您可以使用它进行复制构造a。C++ 声明不能将右值作为非 const 引用传递。Visual Studio 对这条规则有点草率,但 gcc 等强制执行。

要修复,试试这个(这完全一样,但是你通过命名那个变量来创建一个左值)。更多关于 l 和 r 值的信息在这里

A operator*( A a, const A& b )
{
   return a *= b;
}
于 2012-04-19T20:36:56.907 回答