我原本认为通过引用捕获会改变变量的类型。我们来看下面这个例子:
#include <cassert>
#include <type_traits>
int main()
{
int x = 0;
int& x_ref = x;
const int x_const = x;
const int& x_const_ref = x_const;
auto lambda = [&]()
{
static_assert(std::is_same<decltype(x), int>::value, "!");
static_assert(std::is_same<decltype(x_ref), int&>::value, "!");
static_assert(std::is_same<decltype(x_const), const int>::value, "!");
static_assert(std::is_same<decltype(x_const_ref), const int&>::value, "!");
};
lambda();
}
所有检查都没有失败,因此原始变量的类型得以保留。那么,通过引用捕获到底是如何工作的呢?我认为如果用户通过引用捕获,将会在本地作用域中引入具有相同名称的新变量,以引用原始变量的类型。但似乎并非如此。
问题:这样做的动机是什么?还是我误解了什么?
decltype
给出了变量的声明类型;在 lambda 函数内部并不影响声明,因此也不会影响decltype
。 - ildjarndecltype
来说,重要的是声明。 - ildjarndecltype((n))
而不是decltype(n)
,因为后者总是指向原始声明,而前者的行为就好像它指向闭包类型的成员一样(即使名称实际上没有被捕获!)。然后它将给出表达式的类型。据我所知,使用decltype
无法获取闭包类型的成员声明的类型。您要么获取原始声明的类型,要么获取闭包成员引用的表达式类型(对于mutable
/默认lambda有所区别)。 - Johannes Schaub - litb#include <cassert>
就可以使用static_assert
。 - Oktalist