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

ルシアンが言ったように、一時オブジェクトを非 const 参照にバインドすることはできません。コンパイラは、オブジェクトが式の後に存在しなくなることを期待しているため、オブジェクトを変更しても意味がありません。

コードを修正するには、一時的なものを削除します (引数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 に答える