1. ホーム
  2. c++

[解決済み] C++11 auto: 定数参照を取得したらどうする?

2023-07-11 10:20:18

質問

次の簡単なコードを見てください。

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 への定数参照となります。しかし、その型は autoFoo であり、参照ではありません。さらに my_foo をコピーすることで作成されます。 g_temp . この動作は、私にはそれほど明白ではありません。

への参照を取得するために Foo への参照を得るには、このように書く必要がありました。

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

質問 : なぜ auto の戻り値の型を推論しているのでしょうか? GetFoo を参照ではなく、オブジェクトとして推論してください。

どのように解決するのですか?

この記事を読む C++における定数の表示と非表示


C++0x の自動変数の型控除は、基本的にテンプレート パラメータの型控除と同じです。 テンプレート パラメータに対するものと基本的に同じです。(私の知る限り、唯一の違いは この 2 つの違いは、自動変数の型はイニシャライザー リストから推論される可能性があるのに対し テンプレート・パラメータの型は推論できませんが,自動変数の型はイニシャライザー・リストから推論できます). したがって,次の各宣言は,以下の型の変数を宣言していることになる. int型の変数を宣言しています(決してconst intではありません).

auto a1 = i;
auto a2 = ci;
auto a3 = *pci;
auto a4 = pcs->i;

<ブロッククオート

テンプレートパラメータと自動変数の型推論では、トップレベルの定数のみが削除されます。 のみが削除されます。を取る関数テンプレートがある場合 ポインタまたは参照パラメータを取る関数テンプレートでは、ポインタまたは参照されるものの定数は保持されます。 の定数は保持されます。

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-qualifierを保持できるので、できます。

auto& my_foo2 = GetFoo();

と指定するのではなく const (のように指定する必要はありません(同じように volatile ).

編集してください。 なぜかというと auto の戻り値の型を推論しています。 GetFoo() を参照ではなく値として推論することができます(これはあなたの主な質問でした、すみません)、これを考えてみましょう。

const Foo my_foo = GetFoo();

上記はコピーを作成します。 my_foo は値だからです。もし auto がlvalueの参照を返すのであれば、上記は不可能でしょう。