web-dev-qa-db-ja.com

C ++ 11 auto:定数参照を取得するとどうなりますか?

次の簡単なコードをご覧ください。

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_foog_tempをコピーして作成されます。この動作は私にはそれほど明白ではありません。

Fooへの参照を取得するには、次のように記述する必要がありました。

const auto& my_foo2 = GetFoo();
      auto& my_foo3 = GetFoo();

質問autoGetFooの戻り値の型を参照ではなくオブジェクトとして推定するのはなぜですか?

69
minjang

この記事を読む: 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:autoGetFoo()の戻り値の型を参照ではなく値として推定する理由(これはあなたの主な質問でした、申し訳ありません)、これを考慮してください:

_const Foo my_foo = GetFoo();
_

_my_foo_は値であるため、上記はコピーを作成します。 autoが左辺値参照を返す場合、上記は不可能です。

61
someguy