2013-11-27 8 views
14

Następujące nie skompilować chyba kładę constexpr przed initializer_list:Dlaczego wymagany jest constexpr, mimo że funkcja member jest constexpr?

constexpr std::initializer_list<int> il = { 
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10 
}; 
std::array<int, il.size()> a; 

Ale initializer_list rozmiar jest constexpr:

constexpr size_type size() const; 
+1

Nie jest nawet jasne, czy 'constexpr std :: initializer_list li = {..};' jest poprawne w C++ 11; będzie w C++ 1y. – dyp

Odpowiedz

32
std::initializer_list<int> il = rand() ? std::initializer_list<int>{1} 
             : std::initializer_list<int>{1,2,3}; 

std::array<int, il.size()> a; 

dlatego.

Funkcja członkowska to funkcja, która może być wykonywana w ramach wyrażenia stałego, niekoniecznie daje wynik, który jest stałą czasu kompilacji. Na przykład:

struct S 
{ 
    int m; 
    constexpr int foo() const { return m; } 
}; 

S s{rand()}; 
int j = s.foo();  // only known at run-time 

constexpr S cs{42}; 
int arr[cs.foo()]; // compile-time constant 
2

Pisząc std::array<int, il.size()> a; jesteś twierdząc, że il.size() można ocenić w czasie kompilacji ze stałą rezultacie pozwalając szablonu konkretyzacji.

Dlatego zarówno metoda initializer_list::size() a il zmienne muszą być zadeklarowane jako constexpr.