Pourquoi std :: array n’est pas vide?

N’importe quel std::array , pourquoi n’est-il pas vide? Je veux dire “vide” comme dans:

  std::is_empty< std::array >::value 

retournant false et

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

les rendements

  4 4 8 

ce qui signifie que pour std::array , l’optimisation de la base vide (EBO) n’est pas appliquée.

Cela me semble particulièrement étrange étant donné que std::tuple (remarque: aucun paramètre de modèle) est vide, c’est-à-dire que std::is_empty<std::tuple>::value donne true .

Question: Pourquoi est-ce, étant donné que la taille 0 est déjà un cas particulier pour std::array ? Est-ce intentionnel ou un oubli dans la norme?

La norme ne dit pas si le tuple ou le array doit être vide, ce que vous voyez est des détails d’implémentation, mais il n’y a aucune raison de faire du tuple<> non vide, alors qu’il y a une bonne raison pour le array étant non vide, considérez:

 std::array = { { values... } }; 

Lorsque le pack de parameters est vide, vous obtenez:

 std::array = { { } }; 

Pour que l’initialiseur soit valide, l’object a besoin d’un membre, qui ne peut pas être int[0] car vous ne pouvez pas avoir de tableaux de taille zéro en tant que membres, donc une implémentation possible est int[1]

Une implémentation n’a pas à mettre en cas particulier le tableau entier, elle peut juste faire:

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

et tous les autres membres fonctionnent exactement de la même manière (en supposant que end() est défini par begin()+N )