在 lambda 中通过显式 this 参数访问捕获的变量
Accessing captured variables through explicit this parameter in lambda
来自declarations / functions / 9.3.4.6 / 6.2 (我很抱歉如何引用标准中的特定句子):
An explicit-object-parameter-declaration is a parameter-declaration with a this specifier. An explicit-object-parameter-declaration shall appear only as the first parameter-declaration of a parameter-declaration-list of either: (6.1) a member-declarator that declares a member function ([class.mem]), or (6.2) a lambda-declarator ([expr.prim.lambda]).
如果lambda表达式允许this
作为显式对象参数,当我们同时捕获变量时会发生什么?
根据我的理解,如果我们有 lambda:
[x = 2](this auto& func) { x = 4; }();
可能大致相当于:
class lambda01 {
private:
int x;
public:
constexpr lambda01(cons int& x_)
: x{x_} {}
constexpr void operator()(this lambda01& func) {
func.x = 4;
}
};
lambda04 lambda04_obj {2};
lambda04_obj.operator()();
如果是对的。
例如没有。 1:
int x;
// is it:
[&x](this auto& func){ x = 4; }();
assert(x == 4);
// or:
[&x](this auto& func){ func.x = 2; }();
assert(x == 2);
- 两个表达式都有效吗?
- lambda 取左值对象参数有效吗?
例如没有。 2 将以可变参数打印参数:
[]<typename... Args>(const Args&... args) {
[&](this auto func){
/** ... **/
};
}(1, 2, 3, 4);
从评论的表达式中,哪一个是有效的?
(std::cout << args << '\n', ...)
(std::cout << func.args << '\n', ...)
- 两者
- 都没有
如果第二个选择有效,那么关于 1 个对象中可能的参数包的另一个问题就值得了。
简而言之,在带显式对象参数的 lambda 中使用点运算符访问的捕获变量是否有效?
标准不允许:
For each entity captured by copy, an unnamed non-static data member is declared in the closure type.
如果是“未命名”,则不能命名。有一种特定的语言可以将捕获的实体的名称转换为基于 this
的表达式,但仅此而已。
因此您可以采用明确的 this
参数,捕获实体的名称将自动使用该参数。但是你不能通过显式参数访问这些变量。
在 lambda 中显式采用 this
的唯一原因是使用标准提供的接口:调用 lambda。又名:递归调用 lambda 而不 命名 lambda。
来自declarations / functions / 9.3.4.6 / 6.2 (我很抱歉如何引用标准中的特定句子):
An explicit-object-parameter-declaration is a parameter-declaration with a this specifier. An explicit-object-parameter-declaration shall appear only as the first parameter-declaration of a parameter-declaration-list of either: (6.1) a member-declarator that declares a member function ([class.mem]), or (6.2) a lambda-declarator ([expr.prim.lambda]).
如果lambda表达式允许this
作为显式对象参数,当我们同时捕获变量时会发生什么?
根据我的理解,如果我们有 lambda:
[x = 2](this auto& func) { x = 4; }();
可能大致相当于:
class lambda01 {
private:
int x;
public:
constexpr lambda01(cons int& x_)
: x{x_} {}
constexpr void operator()(this lambda01& func) {
func.x = 4;
}
};
lambda04 lambda04_obj {2};
lambda04_obj.operator()();
如果是对的。
例如没有。 1:
int x;
// is it:
[&x](this auto& func){ x = 4; }();
assert(x == 4);
// or:
[&x](this auto& func){ func.x = 2; }();
assert(x == 2);
- 两个表达式都有效吗?
- lambda 取左值对象参数有效吗?
例如没有。 2 将以可变参数打印参数:
[]<typename... Args>(const Args&... args) {
[&](this auto func){
/** ... **/
};
}(1, 2, 3, 4);
从评论的表达式中,哪一个是有效的?
(std::cout << args << '\n', ...)
(std::cout << func.args << '\n', ...)
- 两者
- 都没有
如果第二个选择有效,那么关于 1 个对象中可能的参数包的另一个问题就值得了。
简而言之,在带显式对象参数的 lambda 中使用点运算符访问的捕获变量是否有效?
标准不允许:
For each entity captured by copy, an unnamed non-static data member is declared in the closure type.
如果是“未命名”,则不能命名。有一种特定的语言可以将捕获的实体的名称转换为基于 this
的表达式,但仅此而已。
因此您可以采用明确的 this
参数,捕获实体的名称将自动使用该参数。但是你不能通过显式参数访问这些变量。
在 lambda 中显式采用 this
的唯一原因是使用标准提供的接口:调用 lambda。又名:递归调用 lambda 而不 命名 lambda。