Why can#39;t a const mutable lambda with an autoamp; parameter be invoked?(为什么不能调用带有自动amp;参数的常量可变lambda?)
问题描述
#include <type_traits>
int main()
{
auto f1 = [](auto&) mutable {};
static_assert(std::is_invocable_v<decltype(f1), int&>); // ok
auto const f2 = [](auto&) {};
static_assert(std::is_invocable_v<decltype(f2), int&>); // ok
auto const f3 = [](auto&) mutable {};
static_assert(std::is_invocable_v<decltype(f3), int&>); // failed
}
参见demo
为什么常量可变lambda不能接受引用参数?
推荐答案
这里有两件有趣的事情。
首先,lambda的调用操作符(模板)默认为const。如果您提供mutable,则它不是const。mutable对lambda的影响仅与正常成员函数中的尾随const的影响相反(它不影响lambda捕获等)
所以如果你看这个:
auto const f3 = [](auto&) mutable {};
static_assert(std::is_invocable_v<decltype(f3), int&>); // failed
这是一个const对象,其调用操作符模板(因为它是一个泛型lambda)是非const。因此您不能调用它,因为您不能在任何其他上下文中调用const对象上的非const成员函数。请参阅this other answer。
第二,有人指出,尽管如此,这是可行的:
auto const f4 = [](int&) mutable {}; // changed auto& to int&
static_assert(std::is_invocable_v<decltype(f4), int&>); // now ok
这是而不是编译器错误。也不是意味着我刚才说的是错的。f4仍然有非常数调用运算符。您无法调用它,因为f4是一个常量对象。
但是。
lambdas没有捕获的另一个有趣的方面是:它们有一个将函数转换为函数指针类型的函数。也就是说,我们通常认为lambdaf4是这样的:
struct __unique_f4 {
auto operator()(int&) /* not const */ { }
};
如果这就是整个故事,const __unique_f4确实不能用int&调用。但它实际上看起来是这样的:
struct __unique_f4 {
auto operator()(int&) /* not const */ { }
// conversion function to the appropriate function
// pointer type
operator void(*)(int&)() const { /* ... */ }
};
我们有这样一个规则,当您调用一个对象时,例如f(x),您不仅要考虑f的调用运算符--那些名为operator()的成员--而且还要考虑f的任何surrogate call functions--是否有任何函数指针可以转换为f,然后调用。
在这种情况下,您可以!您可以将f4转换为void(*)(int&),该函数指针可通过int&调用。
但这仍然意味着f4的调用运算符不是const,因为您声明了它是可变的。而且它没有说明您是否可以让mutablelambdas获取引用参数。
这篇关于为什么不能调用带有自动&;参数的常量可变lambda?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么不能调用带有自动&;参数的常量可变lambda?
基础教程推荐
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 这个宏可以转换成函数吗? 2022-01-01
- 常量变量在标题中不起作用 2021-01-01
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 我有静态或动态 boost 库吗? 2021-01-01
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
