web-dev-qa-db-ja.com

c ++ 11のポインターの「自動」型割り当てには「*」が必要ですか?

私の変数がポインターであると仮定して、「auto」型の変数に割り当てる場合、「*」を指定しますか?

std::vector<MyClass> *getVector(); //returns populated vector
//...

std::vector<MyClass> *myvector = getVector();  //assume has n items in it
auto newvar1 = myvector;

// vs:
auto *newvar2 = myvector;

//goal is to behave like this assignment:
std::vector<MyClass> *newvar3 = getVector();

このautoがc ++ 11でどのように機能するかについて少し混乱しています(これはc ++ 11の新機能ですよね?)

更新:上記の内容を修正して、ベクトルが関数に実際に取り込まれる方法をより明確にし、返されたポインターを変数に割り当てようとしています。混乱させて申し訳ありません

43
Dolan Antenucci
_auto newvar1 = myvector;

// vs:
auto *newvar2 = myvector;
_

これらは両方とも同じで、_std::vector<MyClass>_へのポインターを宣言します myvectorはこの例では初期化されておらず、ガベージが含まれている可能性があるため、ランダムな場所を指します)。したがって、基本的にはいずれかを使用できます。私はauto var = getVector()を好むでしょうが、varがポインターであるという意図を強調していると思われる場合は、auto* var = getVector()に行くことができます。

autoを使用して、同様の不確実性を夢見ていないと言わなければなりません。人々はautoを使用するだけで、それについて考えないだろうと思っていました。これは99%正しいです-autoを何かで装飾する必要があるのは、参照とcv修飾子のみです。

ただし、わずかに変更すると、2つの間にわずかな違いisがあります。

_auto newvar1 = myvector, newvar2 = something;
_

この場合、_newvar2_はポインターになります(何かが必要です)。

_auto *newvar1 = myvector, newvar2 = something;
_

ここで、_newvar2_は、たとえば、 _std::vector<MyClass>_、および初期化子が適切でなければなりません。

一般に、初期化子がブレース付きの初期化子リストではない場合、コンパイラはautoを次のように処理します。

  1. autoがtemplateパラメーターに置き換えられた、宣言子の正確な形式の引数を1つ持つ人工関数テンプレート宣言を生成します。したがって、_auto* x = ..._には、

    _template <class T> void foo(T*);
    _
  2. 呼び出しfoo(initializer)を解決しようとし、Tの推論を探します。これは、autoの代わりに置き換えられます。

  3. 単一の宣言にさらに宣言子がある場合、これはすべての宣言子に対して行われます。推定されるTは、それらすべてで同じでなければなりません...

43
jpalecek
auto newvar1 = *myvector;

これはおそらく、実際のベクトルのコピーを作成するものです。代わりに参照が必要な場合は、auto& newvar1 = *myvector;と書くか、同じベクトルへの別のポインターを作成するには、auto newvar1 = myvector;を使用します。他の試みauto *newvar1 = myvector;との違いは、後者がmyvectorを強制的にポインター型にすることであるため、次のコードは失敗します。

std::vector<int> v1;
auto* v2 = v1; // error: unable to deduce ‘auto*’ from ‘v1’
2
Stacker