次の簡単なコードをご覧ください。
class Foo
{
public:
Foo(){}
~Foo(){}
Foo(const Foo&){}
Foo& operator=(const Foo&) { return *this; }
};
static Foo g_temp;
const Foo& GetFoo() { return g_temp; }
次のようにauto
を使用しようとしました:
auto my_foo = GetFoo();
my_foo
は、関数の戻り値の型であるFoo
への定数参照になると予想しました。ただし、auto
の型はFoo
であり、参照ではありません。さらに、my_foo
はg_temp
をコピーして作成されます。この動作は私にはそれほど明白ではありません。
Foo
への参照を取得するには、次のように記述する必要がありました。
const auto& my_foo2 = GetFoo();
auto& my_foo3 = GetFoo();
質問:auto
がGetFoo
の戻り値の型を参照ではなくオブジェクトとして推定するのはなぜですか?
この記事を読む: C++でのconstの表示と非表示
C++ 0xの自動変数の型推論は、テンプレートパラメーターの場合と本質的に同じです。 (私が知る限り、2つの唯一の違いは、自動変数の型は初期化子リストから推測できるのに対し、テンプレートパラメータの型は推測できないことです。)したがって、次の各宣言はint型の変数を宣言します(決してconst int):
_auto a1 = i;
auto a2 = ci;
auto a3 = *pci;
auto a4 = pcs->i;
_
テンプレートパラメータと自動変数の型推論中に、最上位のconstのみが削除されます。ポインターまたは参照パラメーターを受け取る関数テンプレートを指定すると、ポイントまたは参照されるものの定数が保持されます。
_template<typename T>
void f(T& p);
int i;
const int ci = 0;
const int *pci = &i;
f(i); // as before, calls f<int>, i.e., T is int
f(ci); // now calls f<const int>, i.e., T is const int
f(*pci); // also calls f<const int>, i.e., T is const int
_
この動作は古いニュースであり、C++ 98とC++ 03の両方に適用されます。自動変数の対応する動作は、もちろんC++ 0xの新機能です。
_auto& a1 = i; // a1 is of type int&
auto& a2 = ci; // a2 is of type const int&
auto& a3 = *pci; // a3 is also of type const int&
auto& a4 = pcs->i; // a4 is of type const int&, too
_
型が参照またはポインターである場合、cv修飾子を保持できるため、次のことができます。
_auto& my_foo2 = GetFoo();
_
const
として指定する代わりに(volatile
でも同じです)。
Edit:auto
がGetFoo()
の戻り値の型を参照ではなく値として推定する理由(これはあなたの主な質問でした、申し訳ありません)、これを考慮してください:
_const Foo my_foo = GetFoo();
_
_my_foo
_は値であるため、上記はコピーを作成します。 auto
が左辺値参照を返す場合、上記は不可能です。