15

autoとdecltypeに問題があります。

void f(const vector<int>& a, vector<float>& b)
{
    typedef decltype(a[0]*b[0]) Tmp;
    for (int i=0; i < b.size(); ++i) {
      auto p0 = new auto(a[i]*b[i]);
      auto p1 = new decltype(a[i]*b[i]);
      *p0=a[i]*b[i];
      *p1=a[i]*b[i];
      cout<<*p0<<endl;
      cout<<*p1<<endl;
      delete p0;
      delete p1;
   }
}

 int main()
{

    vector<float>vec2;
    vec2.push_back(2.0);

    vector<int>vec1;
    vec1.push_back(5);

    return 0;
}

上記のコードはGCC4.7でうまく動作します。'new auto(a [0] * b [0])'を使用して、タイプa [0] * b [0]にメモリを割り当てることはできますか?そして、この場合、decltypeとautoの違いを区別することはできません。

4

1 に答える 1

19

違いは次のとおりです。

  new auto(a[i]*b[i]);

は、任意のタイプのオブジェクトを割り当て、その値でオブジェクトa[i]*b[i]初期化します。つまり、括弧は初期化子です。一方、decltypeを使用する場合:

  new decltype(a[i]*b[i]);

同じタイプのオブジェクトを割り当てますが、初期化子はありません。オブジェクトはデフォルトで初期化されています。

基本的decltype(...)には型として扱われautoますが、初期化子から推定される型を指定します。


C++11スタイル

new特別な場合を除いて使用すべきではないため、何らかの理由でこれらのセマンティクスが必要な場合は、次のように適切に記述されます。

template<typename T, typename... Args> T make_unique(Args &&...args) {
  return std::unique_ptr<T>{std::forward<Args>(args)...};
}

template<typename T> T make_unique_auto(T &&t) {
    return std::unique_ptr<T>{std::forward<T>(t)};
}

// new auto(a[i]*b[i])
auto p1 = make_unique_auto(a[i]*b[i]);

// new decltype(a[i]*b[i])
auto p2 = make_unique<decltype(a[i]*b[i])>();

さらに、C ++ 11の統一初期化を普遍的に使用することに慣れていて、初期化に括弧の使用をdecltypeやめると、最終的には、で使用される括弧は初期化子のようにプログラマーに見えなくなります。

この理由やその他の理由から、「最新の」C ++ 11スタイルには、初期化に常に中括弧を使用し、括弧を使用しないというルールを含めるとよいと思います。(たとえば、かっこ以外で呼び出すことができないコンストラクターはstd::vector<int>(int,int);避ける必要があります。新しいコンストラクターを作成したり、レガシーコンストラクターを使用したりしないでください。)

于 2012-06-07T15:30:26.920 に答える