2013-03-20 37 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

相关问题