2013-03-20 80 views
20

鑑於任何std::array< T, 0 >,它爲什麼不是空的?我的意思是 「空」,如下所示:爲什麼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的特例?這是標準中的故意還是疏忽?

回答

21

該標準並沒有說是否tuplearray應該是空的東西,你看到的是實施細節,但沒有理由讓tuple<>非空,而有一個很好的理由array<T, 0>是非-empty,考慮:

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

當參數包是空的,你會得到:

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

對於初始化爲有效的對象需要的會員,這不可能是int[0],因爲你不能有零大小的數組作爲成員,因此,一個可能的實現是int[1]

的實現並不一定特例整個陣列,它可以這樣做:

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

和所有其他成員的工作完全一樣的方式(假設end()被定義爲begin()+N

+0

GCC 4.8似乎以不同的方式做到這一點(或的libstdC++與它的到來),由於'的sizeof(標準::陣列)== 1'。但我意識到你說過「一個可能的實施」,我接受這個推理,所以謝謝! – 2013-03-20 00:17:11

+0

GCC做了'value_type _M_instance [_Nm? _Nm:1];''我看到'sizeof(array )== sizeof(int)' – 2013-03-20 00:25:23

+0

我在LiveWorkSpace.org上看到GCC 4.8的sizeof(std :: array )== 1'。奇怪。 – 2013-03-20 00:29:20

相關問題