CTTCG 附录 B Value Categories
对于变量而言,其括号表达式的值类别是左值引用。但由于 decltype
有特殊效果,直接对变量 x
使用 decltype(x)
并不遵循这一点,为此可以按照下面说的使用 decltype((x))
。
With the keyword decltype (introduced in C++11), it is possible to check the value category of any C++ expression. For any expression
x
,decltype((x))
(note the double parentheses) yields:
type
ifx
is a prvaluetype&
ifx
is an lvaluetype&&
ifx
is an xvalueThe double parentheses in
decltype((x))
are needed to avoid producing the declared type of a named entity in case where the expressionx
does indeed name an entity (in other cases, the paren-theses have no effect). For example, if the expressionx
simply names a variablev
, the construct without parentheses becomesdecltype(v)
, which produces the type of the variablev
rather than a type reflecting the value category of the expressionx
referring to that variable.
例子:
#include <iostream>
template<typename T>
struct value_category {
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";
};
// Get value category of an expression
#define VALUE_CATEGORY(expr) value_category<decltype((expr))>::value
#define PRINT(expr) printf("(%s) : %s\n", #expr, VALUE_CATEGORY(expr))
int main() {
PRINT(4); // prvalue
int x;
int &y = x;
int &&z = (int &&)x;
PRINT(x); // lvalue
PRINT(y); // lvalue
PRINT(z); // lvalue
PRINT(x+1); // prvalue
}