为什么'mutable' lambda 函数属性,而不是捕获类型?
Why is 'mutable' a lambda function attribute, instead of being a capture type?
为什么 c++11 要求我们编写:
[a,b]() mutable { a=7; } // b is needlessly mutable, potential source of bugs
而不是:
[mutable a,b]() { a=7; } // no problems here
这是一个疏忽,被认为不够重要,还是有特定的技术原因?
在 n2651 中提到了您的建议:
可以扩展 lambda 表达式的语法以允许声明 是否应将闭包成员声明为可变成员。
这种方法可能会让程序员感到困惑,因为可变性不是一个 闭包对象的属性,而是存储在 关闭。
我不知道这是否是唯一的原因,但似乎确实考虑过。 然而,在赫伯·萨特的提议中,他建议摆脱mutable
,不要隐式地const
捕获副本,这样我们可能会再次看到变化。
可能是各种疏忽(与不能使用 rvalue refs 的方式相同)和 lambda 概念实现方式的工件。
int a;
int* b;
float c;
auto lambda1 = [&a, b, c](int d) mutable -> void {};
class lambda1 {
public:
void operator()(int d) {}
private:
int& a_;
int* b_;
float c_;
};
auto lambda2 = [&a, b, c](int d) -> void {};
class lambda2 {
public:
void operator()(int d) const {}
private:
int& a_;
int* b_;
float c_;
};
mutable
关键字适用于 lambda 表达式生成的对象,而不是单个捕获的项目,以便编译器可以使用operator()
方法上的const
修饰符实现它,如标准第 5.1.2 节第 5 段中所述。
此函数调用运算符声明为 const (9.3.1) 当且仅当 lambda表达式的参数声明子句后面不跟 可变。
在您的示例中,lambda 表达式生成的类可能如下所示:
class lambda
{
int a, b;
public:
lambda( int a, int b ) : a( a ), b( b ) {}
void operator()() // non-const due to mutable keyword
{
a = 7;
}
};
mutable
关键字不像通常使用的mutable
关键字那样使用:在这种情况下,它的意思是与const
相反,适用于函数调用运算符隐式函数对象的恒定性。但是,有意将隐式函数对象的函数调用运算符默认const
,而通常成员函数是非const
("可变")而是默认的。lambda函数的引入早于上下文关键字(override
和final
)的使用,mutable
关键字似乎是比not const
更好的选择。
相关文章:
- 用概念检查属性的类型
- 变量(或属性)可以等于类型吗?
- C++类型的属性是继承的吗
- 如何在一个属性中动态存储基元类型
- C++将两个不同类型的向量的属性连接到新的向量中
- 将提升属性映射与捆绑类型一起使用
- 使用类属性调用具有非类型模板参数的模板函数
- 如何在提升图形库中获取属性的类型
- 我创建了deque<CObject*>并添加了不同类型的元素。如何更改此元素的属性?
- 应用于类型别名声明的 [[maybe_unused]] 属性的语法
- 访问用户定义类型的数组的特定属性
- 精神X3,如何获得属性类型以匹配规则类型
- 具有相似属性的不同数据类型的模板
- 如何从Google Proto Buf消息中的属性名称中找到消息类型
- 创建具有受限属性的类型
- 支持 g++ 中的类型属性
- 限制数据类型属性冲突-ODBC with Access Database
- 为虚拟析构函数指定的冲突类型属性
- Cython扩展类型属性误解
- 绕过c++的静态类型属性