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,因为您声明了它是可变的。而且它没有说明您是否可以让mutable
lambdas获取引用参数。
这篇关于为什么不能调用带有自动&;参数的常量可变lambda?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么不能调用带有自动&;参数的常量可变lambda?


基础教程推荐
- C++,'if' 表达式中的变量声明 2021-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 设计字符串本地化的最佳方法 2022-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01