2013-11-27 21 views
14

Sau đây không biên dịch, trừ khi tôi đưa constexpr trước initializer_list:Tại sao yêu cầu constexpr mặc dù hàm thành viên là constexpr?

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

Nhưng initializer_list kích thước là constexpr:

constexpr size_type size() const; 
+1

Nó thậm chí không rõ ràng nếu 'constexpr std :: initializer_list li = {..};' là hợp lệ trong C++ 11; nó sẽ có trong C++ 1y. – dyp

Trả lời

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; 

Đó là lý do tại sao.

A constexpr chức năng thành viên là một chức năng mà có thể được thực thi trong một biểu thức không đổi, nó không nhất thiết mang lại kết quả là hằng số biên dịch. Ví dụ:

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

Bằng cách viết std::array<int, il.size()> a; bạn đang tuyên bố rằng il.size() có thể được đánh giá ở thời gian biên dịch với một kết quả không đổi, cho phép mẫu instantiation.

Đó là lý do tại sao cả phương pháp initializer_list::size() và biến số il của bạn cần phải được khai báo là constexpr.

Các vấn đề liên quan