24

あるとすればstd::array< T, 0 >、なぜそれは空ではないのですか?私は次のように「空」を意味します:

 std::is_empty< std::array< int, 0 > >::value

戻っfalse

 #include <iostream>
 #include <tuple>
 #include <array>

 struct Empty {};

 int main()
 {
     std::cout << sizeof(std::tuple<int>) << std::endl;
     std::cout << sizeof(std::tuple<int,Empty>) << std::endl;
     std::cout << sizeof(std::tuple<int,std::array<int,0>>) << std::endl;
 }

収量

 4
 4
 8

つまり、std::array<int,0>の場合、空のベース最適化(EBO)は適用されません。

std::tuple<>(注:テンプレートパラメータがない)空である、つまり、をstd::is_empty<std::tuple<>>::value生成することを考えると、これは私には特に奇妙に思えますtrue

質問:サイズ0がすでに特殊なケースであるとすると、それはなぜstd::arrayですか?それは意図的なものですか、それとも規格の見落としですか?

4

1 に答える 1

25

標準では、空にするかどうかについては何も述べられていませんtuplearray表示されているのは実装の詳細ですが、空でないようにする理由はありませんが、tuple<>空でない理由は十分にあります。次のarray<T, 0>ことを考慮してください。

std::array<int, sizeof...(values)> = { { values... } };

パラメータパックが空の場合、次のようになります。

std::array<int, 0> = { { } };

初期化子が有効であるためには、オブジェクトにメンバーが必要です。これは、メンバーint[0]としてサイズがゼロの配列を使用できないため、メンバーが必要になるため、実装の可能性は次のとおりです。int[1]

実装は、配列全体を特別なケースにする必要はありません。次のことを実行できます。

T m_data[N == 0 ? 1 : N];

他のすべてのメンバーはまったく同じように機能します(end()と定義されていると仮定しますbegin()+N

于 2013-03-20T00:10:10.427 に答える