xml*_*lmx 29 c++ lambda static-assert type-traits c++20
#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
}
Run Code Online (Sandbox Code Playgroud)
查看演示
为什么 const mutable lambda 不能采用引用参数?
Bar*_*rry 33
这里有两件有趣的事情。
首先,lambda 的调用运算符(模板)是const
默认的。如果你提供了mutable
,那就不是const
。mutable
lambda 对 lambda的影响与普通成员函数中尾随的影响完全const
相反(它不影响 lambda 捕获等)
所以如果你看看这个:
auto const f3 = [](auto&) mutable {};
static_assert(std::is_invocable_v<decltype(f3), int&>); // failed
Run Code Online (Sandbox Code Playgroud)
这是一个const
对象,其调用运算符模板(因为它是通用 lambda)是非const
。所以你不能调用它,出于同样的原因,你不能在任何其他上下文中调用对象const
上的非成员函数const
。请参阅另一个答案。
其次,有人指出,尽管如此,这是有效的:
auto const f4 = [](int&) mutable {}; // changed auto& to int&
static_assert(std::is_invocable_v<decltype(f4), int&>); // now ok
Run Code Online (Sandbox Code Playgroud)
这不是编译器错误。也不代表我刚才说的就是错的。f4
仍然有一个非常量调用运算符。您无法调用它,因为它f4
是一个 const 对象。
然而。
没有捕获的 lambda 表达式还有另一个有趣的方面:它们有一个到函数指针类型的转换函数。也就是说,我们通常认为 lambdaf4
看起来像这样:
struct __unique_f4 {
auto operator()(int&) /* not const */ { }
};
Run Code Online (Sandbox Code Playgroud)
而且,如果这就是整个故事,const __unique_f4
确实不能用 来调用int&
。但实际上看起来是这样的:
struct __unique_f4 {
auto operator()(int&) /* not const */ { }
// conversion function to the appropriate function
// pointer type
operator void(*)(int&)() const { /* ... */ }
};
Run Code Online (Sandbox Code Playgroud)
我们有一条规则,当您调用一个对象时,例如f(x)
,您不仅考虑 的f
调用运算符 - 那些命名的成员operator()
- 而且您还考虑任何 的f
代理调用函数- 是否有任何函数指针您可以转换f
为,然后调用。
在这种情况下,你可以!您可以转换f4
为 avoid(*)(int&)
并且该函数指针可以使用 调用int&
。
但这仍然意味着f4
's 调用运算符不是 const,因为您声明它是可变的。并且它没有说明是否可以让mutable
lambda 接受引用参数。
for*_*818 13
出于同样的原因,您会收到错误消息:
struct foo {
void operator()(){}
};
int main() {
const foo f;
f();
}
Run Code Online (Sandbox Code Playgroud)
错误是:
<source>:7:5: error: no matching function for call to object of type 'const foo'
f();
^
<source>:2:10: note: candidate function not viable: 'this' argument has type 'const foo', but method is not marked const
void operator()(){}
^
Run Code Online (Sandbox Code Playgroud)
因为你不能在 const 实例上调用非常量方法。Lambdas的默认常量是正确的,所以没有mutable
is 。是一个非常量方法,您不能调用operator()
const
mutable
operator()
const f3;
归档时间: |
|
查看次数: |
1472 次 |
最近记录: |