#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
}
见演示
为什么常量可变lambda不能接受引用参数?
由于同样的原因,您会因此而出错:
struct foo {
void operator()(){}
};
int main() {
const foo f;
f();
}
错误是:
<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()(){}
^
因为不能在常量实例上调用非常量方法。Lambdas获得了正确的默认常量,因此如果没有mutable
,操作符()
就是const
。使用mutable
时,操作符()
是一个非常量方法,您不能调用常量f3
这里有两件有趣的事情。
首先,lambda的调用操作符(模板)默认为const
。如果您提供了mutable
,那么它就不是const
。在正常成员函数中,mutable
对lambda的影响与trailingconst
的影响完全相反(它不影响lambda捕获等)
所以如果你看这个:
auto const f3 = [](auto&) mutable {};
static_assert(std::is_invocable_v<decltype(f3), int&>); // failed
这是一个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
这不是编译器错误。也不意味着我刚才说的是错的。f4
仍然有一个非const调用操作符。不能调用,因为f4
是一个const对象。
然而。
lambda还有一个有趣的方面没有捕获:它们有一个到函数指针类型的转换函数。也就是说,我们通常认为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
的调用运算符--那些名为运算符()
的成员--而且还要考虑f
的代理调用函数--是否有任何函数指针可以将f
转换为,然后调用。
在这种情况下,你可以!您可以将
f4
转换为space(*)(int
但这仍然意味着
f4
的调用操作符不是常量,因为您声明它是可变的。它没有说明是否可以使用mutable
lambdas引用参数。
这个问题与前一个问题相关,在前一个问题中,我们注意到init捕获lambdas与Boost的范围和迭代器不兼容,因为一些相当模糊且嵌套很深的故障可能很难通过破解Boost来解决。射程源。 接受的答案建议将lambda存储在对象中。为了避免潜在的函数调用开销,我编写了两个函数对象,可以作为潜在的解决方法。它们在下面的代码中被称为和 不使用和编译行,并正确打印行的的实例。 然而,标准草案提到 5.1.
我在读关于不可变类的书,而使类不可变的方法据说是: 1-使类成为最终类以防止继承 我认为第三个条件是不必要的。当我们使一个变量最终并为它提供任何值时,在那之后,即使通过方法也不能给它赋值(因为一旦赋值给它,最终变量就不能改变)。那么为什么我们需要第三个条件没有setter方法呢? 我是不是理解错了?
我很惊讶地看到这个程序甚至可以编译,但结果更让我惊讶: 交换功能在库中实现为: 其中是一个可变的Java列表,而不是不可变的静态编程语言列表。所以我认为其他Java函数也可以工作。例如: 工作,但其他函数,例如函数,甚至不编译: 生成以下错误消息: 类型推断失败:趣味填充(p0:可变列表!,p1:T!):无法将单位应用于(List,Int)类型不匹配:推断的类型为List,但为MutableLis
本文向大家介绍String 为什 么是不可变的?相关面试题,主要包含被问及String 为什 么是不可变的?时的应答技巧和注意事项,需要的朋友参考一下 简单的来说:String 类中使用 final 关键字修饰字符数组来保存字符串,`private final char value[]`,所以 String 对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 Ab
问题内容: 我试图为对象类型分配一个lambda: 它给我一个错误的说法: 为什么会这样,怎么做? 问题答案: 这是不可能的。根据错误消息不是功能接口,即具有单个公共方法的接口,因此您需要使用引用类型,例如
基本上,我试图用一个名为“a”的变量设置数组的长度,并将其声明为3和int。当我试图用for循环查看所有元素时,我不会将“null”作为元素。到现在为止,一直都还不错。然而,当有人想向该数组中添加一个元素时,我会向提到的变量“a”中添加1,从而延长该数组的长度,并允许我向该数组中再添加一个元素。但它不起作用。以下是代码: }