2013-05-19 17 views
21

Mỗi biểu thức trong C++ 11 có một loại giá trị. Một trong các giá trị lvalue, xvalue hoặc prvalue.Thực nghiệm xác định danh mục giá trị của biểu thức C++ 11?

Có cách nào để viết macro, cho bất kỳ biểu thức nào làm đối số, sẽ tạo chuỗi "lvalue", "xvalue" hoặc "prvalue" nếu thích hợp không?

Ví dụ:

int main() 
{ 
    int x; 

    cout << VALUE_CAT(x) << endl; // prints lvalue 
    cout << VALUE_CAT(move(x)) << endl; // prints xvalue 
    cout << VALUE_CAT(42) << endl; // prints prvalue 
} 

Làm sao VALUE_CAT được thực hiện?

+0

Điều gì đó dọc theo dòng '#define VALUE_CAT (expr) get_value_description (sizeof SFINAE_test_1 ((expr)), sizeof SFINAE_test_2 ((expr))) ' –

+0

Tôi nghĩ ra điều này nhưng không nghĩ thứ hai là glvalue ... http://ideone.com/ARlW3v –

+0

@BenVoigt Tôi không nghĩ rằng giải pháp dựa trên độ phân giải quá tải có thể hoạt động, vì bộ quá tải không thể phân biệt xvalue với giá trị gia tăng. Nó quá tệ, bởi vì nó có thể có khả năng tránh được một macro hoàn toàn (ví dụ: quá tải các hàm 'constexpr'). (Thực sự tôi rất vui vì không phải như vậy, sẽ làm cho độ phân giải quá tải trở nên phức tạp hơn so với nó đã có!) –

Trả lời

38

decltype có thể trả lại loại được khai báo của một thực thể (do đó tên), nhưng cũng có thể được sử dụng để truy vấn loại biểu thức. Tuy nhiên, trong trường hợp thứ hai, kiểu kết quả được 'điều chỉnh' theo danh mục giá trị của biểu thức đó: một biểu thức giá trị kết quả trong một kiểu tham chiếu lvalue, một xvalue trong một kiểu tham chiếu rvalue và một giá trị chỉ trong loại. Chúng ta có thể sử dụng điều này để lợi ích của chúng tôi:

template<typename T> 
struct value_category { 
    // Or can be an integral or enum value 
    static constexpr auto value = "prvalue"; 
}; 

template<typename T> 
struct value_category<T&> { 
    static constexpr auto value = "lvalue"; 
}; 

template<typename T> 
struct value_category<T&&> { 
    static constexpr auto value = "xvalue"; 
}; 

// Double parens for ensuring we inspect an expression, 
// not an entity 
#define VALUE_CATEGORY(expr) value_category<decltype((expr))>::value 
+2

Tốt. Demo: http://ideone.com/z2RI8s –

+0

+1, ước gì tôi đã nghĩ rằng –

+1

Tôi đã không nhận ra 'decltype'" ánh xạ "loại giá trị biểu thức (lvalue, xvalue, prvalue) thành các loại tham chiếu (tham chiếu lvalue T, tham chiếu rvalue đến T, T). Cảm ơn. –

1

Bạn cũng có thể thử sử dụng chức năng API kêu vang của Classification để trả lại danh mục của các biểu hiện từ một AST kêu vang có chứa biểu thức. Đây là, tất nhiên, phức tạp hơn nhiều so với giải pháp của @ Luc, vì nó đòi hỏi phải tạo ra AST thực tế thông qua clang.

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