構造体/クラスに参照メンバーが含まれていない場合に備えて、コンパイラーがデフォルトのコンストラクター、デフォルトのコピーコンストラクター、およびデフォルトのコピー代入演算子を生成することを考えると、それは明らかです。次に、標準では、一時オブジェクトでメンバー メソッドを呼び出すことが許可されていると考えてください。つまり、非 const 一時オブジェクトで非 const メンバーを呼び出すことができます。
次の例を参照してください。
struct Foo {};
Foo foo () {
return Foo();
}
struct Bar {
private:
Bar& operator = (Bar const &); // forbid
};
Bar bar () {
return Bar();
}
int main () {
foo() = Foo(); // okay, called operator=() on non-const temporarie
bar() = Bar(); // error, Bar::operator= is private
}
あなたが書くなら
struct Foo {};
const Foo foo () { // return a const value
return Foo();
}
int main () {
foo() = Foo(); // error
}
つまり、関数 foo() がconst一時を返すようにすると、コンパイル エラーが発生します。
例を完成させるために、const temporarie のメンバーを呼び出す方法を次に示します。
struct Foo {
int bar () const { return 0xFEED; }
int frob () { return 0xFEED; }
};
const Foo foo () {
return Foo();
}
int main () {
foo().bar(); // okay, called const member method
foo().frob(); // error, called non-const member of const temporary
}
現在の式内にあるように一時的なライフタイムを定義できます。そのため、メンバー変数を変更することもできます。できなかった場合は、非 const メンバー メソッドを呼び出すことができる可能性よりも、不条理に導かれるでしょう。
編集:そして、ここに必要な引用があります:
12.2 一時オブジェクト:
- 3) [...] 一時オブジェクトは、それらが作成されたポイントを (レキシカルに) 含む完全式 (1.9) を評価する最後のステップとして破棄されます。[...]
そして(またはより良い、前に)
3.10 左辺値と右辺値:
- 10) オブジェクトを変更するには、オブジェクトの左辺値が必要です。ただし、特定の状況下では、クラス型の右辺値を使用してその参照先を変更することもできます。[例: オブジェクト (9.3) に対して呼び出されるメンバー関数は、オブジェクトを変更できます。]
使用例: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Named_Parameter