3

これは機能します:

class Foo {};
void external_function(Foo&);
void f() {
  Foo b;                                                                                                                                         
  external_function(b);                                                                                                                          
}

これはしません:

class Foo {};
void external_function(Foo&);
void f() {
  external_function(Foo());
}

クランは次のように述べています。

aac.cc:3:6: note: candidate function not viable: no known conversion from 'Derived' to 'Base &' for 1st argument;

GCC は、実際には次の場合により役立ちます。

aac.cc:7:30: error: invalid initialisation of non-const reference of type ‘Base&’ from an rvalue of type ‘Derived’

Herb Sutter ( http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ ) は、非 const 参照は右辺値に使用できないと述べています。彼の例では意味がありますが、私のものでは意味がありません。オブジェクトは external_function() 呼び出しの間存在するからですよね?

私はそれを機能させる方法を知っています。(上記のように) 右辺値にならないように名前付きオブジェクトを作成するか、const ref を使用します。しかし、私には安全だと思われるため、許可されていない理由を知りたいです。

4

3 に答える 3

9

非 const 左辺値参照に一時的なものをバインドすることはできません。ここでの継承は単なる気晴らしです。

struct Foo{};

void bar(Foo&) {}
void cbar(const Foo&) {}

int main()
{
  Foo f;
  bar(f);      // OK
  bar(Foo());  // ERROR
  cbar(Foo()); // OK: const reference binds to temporary
}

究極の「なぜ?」について。、左辺値参照を介して右辺値を変更できるようにすることは、単にエラーが発生しやすいと見なされます。「The C++ Programming Language, Fourth Edition」§7.7.1からの引用

変数への参照と定数への参照は区別されます。これは、変数に一時変数を導入すると非常にエラーが発生しやすいためです。変数への割り当ては、すぐに消える一時的なものへの割り当てになります。定数への参照にはそのような問題はありません...

于 2013-08-15T10:20:35.307 に答える
1

「理由」は、検出が困難なバグを回避するためです。引数が const でない場合、それは関数がそれを変更しようとしていることを意味します (それ以外の場合は単に const にしてください!) 一時オブジェクトの変更は、意図したとおりに行われない可能性が高く、多くの場合、バグを特定するのが非常に困難です。

于 2013-08-15T20:45:03.023 に答える