2013-03-20 10 views
20

Biorąc pod uwagę dowolny numer std::array< T, 0 >, dlaczego nie jest on pusty? To znaczy "puste" na przykład:Dlaczego std :: array < T, 0 > nie jest pusty?

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

powrocie false i

#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; 
} 

daje

4 
4 
8 

, co oznacza, że ​​dla std::array<int,0> optymalizacja pusty podstawy (EBO) nie jest stosowany .

się to wydawać dziwne, zwłaszcza biorąc pod uwagę, że do mnie std::tuple<> (uwaga: nie ma parametry szablonu) jest pusty, to znaczy std::is_empty<std::tuple<>>::value robi uzyskując true.

Pytanie: Dlaczego jest to, że, biorąc pod uwagę wielkość 0 już jest szczególnym przypadkiem dla std::array? Czy jest to celowe czy też niedopatrzenie w standardzie?

Odpowiedz

21

Standard nie mówi nic o tym, czy tuple lub array powinna być pusta, co widzisz są szczegóły realizacji, ale nie ma powodu, aby tuple<> niepusty, natomiast nie jest dobry powód do bycia non array<T, 0> -empty, należy rozważyć:

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

Gdy paczka parametr jest pusty chcesz dostać:

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

dla inicjatora być ważny obiekt potrzebuje członek, który nie może być int[0], ponieważ nie można mieć zerowej wielkości tablic jako członkowie, więc ewentualna realizacja jest int[1]

Implementacja nie musi szczególnym przypadku całą tablicę, to może po prostu zrobić:

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

i wszyscy inni członkowie działają dokładnie w ten sam sposób (zakładając end() jest zdefiniowany jako begin()+N)

+0

GCC 4.8 wydaje się to zrobić inaczej (lub libstdC++ pochodzących z nim), ponieważ 'sizeof (std :: array ) == 1 '. Ale zdaję sobie sprawę, że powiedziałeś "jedno * możliwe * wdrożenie" i akceptuję uzasadnienie, więc dziękuję! –

+0

GCC ma wartość "value_type _M_instance [_Nm? _Nm: 1]; 'i widzę' sizeof (array ) == sizeof (int) ' –

+0

Widzę' sizeof (std :: array ) == 1' dla GCC 4.8 na LiveWorkSpace.org. Dziwne. –

Powiązane problemy