c++ - 通过 lambda 中的显式 this 参数访问捕获的变量

标签 c++ lambda c++23 explicit-object-parameter

来自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]).

如果this由于 lambda 表达式允许显式对象参数,那么当我们同时捕获变量时会发生什么?

根据我的理解,如果我们有 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 的唯一原因是使用标准提供的接口(interface):调用 lambda。又名:递归调用 lambda,命名 lambda。

关于c++ - 通过 lambda 中的显式 this 参数访问捕获的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69688581/

相关文章:

c++ - 没有模式有异常(exception)是什么意思? (数组中出现次数最多的数)?

c# - C++/zlib/gzip 压缩和 C# GZipStream 解压失败

c# - 循环优化或 lambda 闭合有问题?

c# - 创建调用方法的表达式树

C++23 - stacktrace_entry 类有什么好处?

c++ - std::print() 线程安全吗?它是否存在文本交错问题?

c++ - 这是否提供自动内存管理以及内存控制? shared_ptr<unique_ptr<数据>>?

c# - CreateCompatibleDC(IntPtr.Zero) 返回 IntPtr.Zero

python - 使用 lambda 对字符串列表进行排序并忽略前缀

c++ - 使用 C++ 协程实现views::concat?