16

ここここで、配列と値の初期化について 2 つの質問をしました。しかし、このコードでは、私は迷っています:

#include <iostream>
#include <iomanip>
#include <array>

template <class T, class U = decltype(std::declval<T>().at(0))>
inline U f1(const unsigned int i)
{T x; return x.at(i);}

template <class T, class U = decltype(std::declval<T>().at(0))>
inline U f2(const unsigned int i)
{T x = T(); return x.at(i);}

int main()
{
    static const unsigned int n = 10;
    static const unsigned int w = 20;
    for (unsigned int i = 0; i < n; ++i) {
        std::cout<<std::setw(w)<<i;
        std::cout<<std::setw(w)<<f1<std::array<int, n>>(i);
        std::cout<<std::setw(w)<<f2<std::array<int, n>>(i);
        std::cout<<std::setw(w)<<std::endl;
    }
    return 0;
}

予想どおり、f1値がゼロで初期化されていないため、任意の値を返します。しかし、f2もっぱらゼロ値を返すようです:

                   0                   0                   0
                   1                  61                   0
                   2                   0                   0
                   3                   0                   0
                   4           297887440                   0
                   5               32767                   0
                   6             4196848                   0
                   7                   0                   0
                   8           297887664                   0
                   9               32767                   0

個人的にはf2、任意の値を持つ配列を作成し、それを にコピー/移動すると思いましたx。しかし、そうではないようです。

だから、私は2つの質問があります:

  • なんで?
  • このような状況で、 C++11std::array<T, N>と C スタイルT[N]は同じ動作をしますか?
4

1 に答える 1

18

{}orを初期化子として使用()し、 without を使用すると=、値が初期化されます。暗黙的に宣言されたコンストラクターを持つ型の場合、値の初期化はゼロ初期化を実装します。これは、その名前が示すように、各プリミティブ要素を に設定し0ます。これは、コンストラクターが実行される前に発生しますが、この場合、コンストラクターは何もしません。

コンストラクターは何もしないので (それは自明です)、初期化されていないデータを見ることができます。

C スタイルの配列に関しては、後者は不正であるため、= {}代わりにを使用した場合の動作は似ています。名前付きオブジェクトに一時配列オブジェクトを割り当てるように要求しますが、配列を割り当てることはできません。一方、ブレース初期化子リストを配列に割り当てます。ブレース初期化子リストは、式でもオブジェクトでもない特別な構文構造です。= T()T()= {}

于 2013-08-19T07:48:51.890 に答える