为什么捕获的 lambda 不能应用于 std::valarray?
Why the capturing lambda cannot be applied to the std::valarray?
什么不符合捕获 lambda 传递给 std::valarray
的 apply
方法的条件?
考虑以下代码:
int main()
{
std::valarray<int> arr = {1, 2, 3, 4, 5, 6};
auto arr1 = arr.apply([](int val) { return val * 2; }); // compiles
int n = 3;
auto arr2 = arr.apply([n](int val) { return val * n; }); //does not compile
return 0;
}
靠大肠杆菌生活 http://coliru.stacked-crooked.com/a/f0407046699574fc
在https://gcc.godbolt.org/
上测试过,GCC、MSVC 或 CLang 都不会编译以上代码
原因在std::valarray::apply
的定义中:
valarray<T> apply( T func(T) ) const;
valarray<T> apply( T func(const T&) ) const;
两个成员中func
的类型都是函数类型。当用作另一个函数的参数类型时,它会衰减为函数指针。这些成员函数不接受一般函子。仅指向常规函数的指针。
现在,无捕获 lambda 具有指向函数指针的隐式转换运算符。所以第一个 lambda 被转换为一个 int(*)(int)
这是一个可以执行 lambda 主体的常规函数的地址。
但是捕获状态的 lambda 不能以这种方式转换,并且如您所见,不能作为参数传递给 std::valarray::apply
。
什么不符合捕获 lambda 传递给 std::valarray
的 apply
方法的条件?
考虑以下代码:
int main()
{
std::valarray<int> arr = {1, 2, 3, 4, 5, 6};
auto arr1 = arr.apply([](int val) { return val * 2; }); // compiles
int n = 3;
auto arr2 = arr.apply([n](int val) { return val * n; }); //does not compile
return 0;
}
靠大肠杆菌生活 http://coliru.stacked-crooked.com/a/f0407046699574fc
在https://gcc.godbolt.org/
上测试过,GCC、MSVC 或 CLang 都不会编译以上代码
原因在std::valarray::apply
的定义中:
valarray<T> apply( T func(T) ) const;
valarray<T> apply( T func(const T&) ) const;
两个成员中func
的类型都是函数类型。当用作另一个函数的参数类型时,它会衰减为函数指针。这些成员函数不接受一般函子。仅指向常规函数的指针。
现在,无捕获 lambda 具有指向函数指针的隐式转换运算符。所以第一个 lambda 被转换为一个 int(*)(int)
这是一个可以执行 lambda 主体的常规函数的地址。
但是捕获状态的 lambda 不能以这种方式转换,并且如您所见,不能作为参数传递给 std::valarray::apply
。