为什么变量不是 C++ 中的左值?
Why is a variable not an lvalue in C++?
#include <type_traits>
int main()
{
int n;
n = 0;
// failure!
static_assert(std::is_lvalue_reference_v<decltype(n)>);
}
n
可以放在左边,显然应该是左值。
为什么 static_assert
会失败?
n
确实是一个左值引用,但是decltype(n)
returnsint
,而不是int&
。该机制基于模板类型推导的工作方式。它允许您这样的声明和初始化:
int n = 0;
decltype(n) m = 42;
如果 decltype(n)
产生 int&
,以上代码段甚至无法编译。因此,您可以使编译器满意
static_assert(std::is_lvalue_reference_v<decltype(n)&>);
static_assert(std::is_lvalue_reference_v<std::add_lvalue_reference_t<decltype(n)>>);
但我想这不是重点。
decltype
对 id 表达式有特殊规则,推导它们的类型而不考虑值类别。如果您希望它根据 id 表达式通常具有的值类别推断出类型,您可以将 id 表达式括在括号中:
static_assert(std::is_lvalue_reference_v<decltype((n))>);
(n)
在类型系统中与 n
具有相同的类型和值类别,但未被 decltype
特殊对待。由于表达式是左值,推导的类型将是左值引用类型。
#include <type_traits>
int main()
{
int n;
n = 0;
// failure!
static_assert(std::is_lvalue_reference_v<decltype(n)>);
}
n
可以放在左边,显然应该是左值。
为什么 static_assert
会失败?
n
确实是一个左值引用,但是decltype(n)
returnsint
,而不是int&
。该机制基于模板类型推导的工作方式。它允许您这样的声明和初始化:
int n = 0;
decltype(n) m = 42;
如果 decltype(n)
产生 int&
,以上代码段甚至无法编译。因此,您可以使编译器满意
static_assert(std::is_lvalue_reference_v<decltype(n)&>);
static_assert(std::is_lvalue_reference_v<std::add_lvalue_reference_t<decltype(n)>>);
但我想这不是重点。
decltype
对 id 表达式有特殊规则,推导它们的类型而不考虑值类别。如果您希望它根据 id 表达式通常具有的值类别推断出类型,您可以将 id 表达式括在括号中:
static_assert(std::is_lvalue_reference_v<decltype((n))>);
(n)
在类型系统中与 n
具有相同的类型和值类别,但未被 decltype
特殊对待。由于表达式是左值,推导的类型将是左值引用类型。