为什么 decltype(captured_var) 的行为不如预期?
Why does decltype(captured_var) not behave as expected?
#include <type_traits>
int x = 0;
void f(int const x)
{
static_assert(std::is_const_v<decltype(x)>); // ok
}
int main()
{
int n = 0;
[n, m = n]
{
static_assert(std::is_const_v<decltype(m)>); // ok
static_assert(std::is_const_v<decltype(n)>); // err
};
}
为什么 decltype(captured_var)
没有按预期运行?
注意在decltype(n)
中,n
指的是在main()
中定义的局部变量n
,而不是闭包类型的成员(如你所料) ).
(强调我的)
Every id-expression within the compound-statement of a
lambda-expression that is an odr-use of an entity captured by copy is
transformed into an access to the corresponding unnamed data member of
the closure type.
[Note 7: An id-expression that is not an odr-use refers to the
original entity, never to a member of the closure type. However, such
an id-expression can still cause the implicit capture of the entity. —
end note]
顺便说一句:Gcc 似乎直接为非可变 lambda 声明了数据成员 const
。这就是为什么 decltype(m)
得到 const int
的原因。按照标准,[expr.prim.lambda.capture]/10.2
(强调我的)
The type of such a data member is the referenced type if the entity is a reference to an object, an lvalue reference to the referenced function type if the entity is a reference to a function, or the type of the corresponding captured entity otherwise.
我认为gcc是错误的; decltype(m)
应该导致类型 int
。无论如何,decltype(n)
确实引用了局部变量 n
,您可以通过例如将 n
的类型更改为 int&&
.
#include <type_traits>
int x = 0;
void f(int const x)
{
static_assert(std::is_const_v<decltype(x)>); // ok
}
int main()
{
int n = 0;
[n, m = n]
{
static_assert(std::is_const_v<decltype(m)>); // ok
static_assert(std::is_const_v<decltype(n)>); // err
};
}
为什么 decltype(captured_var)
没有按预期运行?
注意在decltype(n)
中,n
指的是在main()
中定义的局部变量n
,而不是闭包类型的成员(如你所料) ).
(强调我的)
Every id-expression within the compound-statement of a lambda-expression that is an odr-use of an entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type.
[Note 7: An id-expression that is not an odr-use refers to the original entity, never to a member of the closure type. However, such an id-expression can still cause the implicit capture of the entity. — end note]
顺便说一句:Gcc 似乎直接为非可变 lambda 声明了数据成员 const
。这就是为什么 decltype(m)
得到 const int
的原因。按照标准,[expr.prim.lambda.capture]/10.2
(强调我的)
The type of such a data member is the referenced type if the entity is a reference to an object, an lvalue reference to the referenced function type if the entity is a reference to a function, or the type of the corresponding captured entity otherwise.
我认为gcc是错误的; decltype(m)
应该导致类型 int
。无论如何,decltype(n)
确实引用了局部变量 n
,您可以通过例如将 n
的类型更改为 int&&
.