2016-05-15 12 views
2

den folgenden Code Gegeben:sizeof std :: aligned_storage und std :: aligned_union

#include <iostream> 
#include <type_traits> 

int main() { 
    std::aligned_storage<sizeof(double), alignof(double)> storage; 
    std::aligned_union<sizeof(double), double> union_storage; 
    std::cout << sizeof(storage) << '\n'; 
    std::cout << sizeof(union_storage) << '\n'; 
    std::cout << sizeof(double) << '\n'; 
} 

Ich erwarte sizeof(storage) und sizeof(union_storage) größer oder gleich sizeof(double) sein, da sie ein double in der Lage sein zu halten. Allerdings I get the output

1 
1 
8 

Klirren-3.8 und gcc-5.3 beide produzieren diese Ausgabe.
Warum gibt sizeof eine falsche Größe zurück?
Wenn ich Placement neu verwende, um double in storage oder union_storage zu setzen, wäre das undefiniertes Verhalten?

Antwort

9

std::aligned_storage und std::aligned_union sind Typenmerkmale, die ein Mitglied type bereitstellen, das der tatsächliche Typ des Speichers ist. Das Platzieren eines double im Speicher des tatsächlichen Eigenschaftstyps wäre also UB, weil es sich um leere Typen mit nur typedef-Membern handelt.

#include <iostream> 
#include <type_traits> 

int main() 
{ 
    using storage_type = 
     std::aligned_storage<sizeof(double), alignof(double)>::type; 
    using union_storage_type = 
     std::aligned_union<sizeof(double), double>::type; 

    storage_type storage; 
    union_storage_type union_storage; 

    std::cout << sizeof(storage_type) << '\n'; 
    std::cout << sizeof(union_storage_type) << '\n'; 
    std::cout << sizeof(storage) << '\n'; 
    std::cout << sizeof(union_storage) << '\n'; 
    std::cout << sizeof(double) << '\n'; 
    return 0; 
} 

This gives:

8 
8 
8 
8 
8 

Hinweis: Da @ T. C. richtig angemerkt: C++ 14 stellt Alias-Vorlagen zur Verfügung, die auf _t für die Merkmalmerkmale std enden (d. h. std::aligned_storage<L, A>::type === std::aligned_storage_t<L,A>). Der Vorteil ist

  1. Kein typename in Vorlage abhängigen Kontext.
  2. Weniger tippen. ;)
+2

Oder 'aligned_storage_t' usw. in C++ 14. –