【问题标题】:How can I access the `typeid` of a captured this pointer in a lambda?如何在 lambda 中访问捕获的 this 指针的“typeid”?
【发布时间】:2020-06-17 14:28:48
【问题描述】:

我有以下代码:

#include <iostream>

class Bobo
{public:
    int member;
    void function()
    {
        auto lambda = [this]() { std::cout << member << '\n'; };
        auto lambda2 = [this]() { std::cout << typeid(*this).name() << '\n'; };
        lambda();
        lambda2();
    }
};

int main()
{
    Bobo bobo;
    bobo.function();
}

行 std::cout

class <lambda_49422032c40f80b55ca1d0ebc98f567f>

但是,如何访问已捕获的“this”指针,以便 typeid 运算符可以返回类型类 Bobo?

编辑:我得到的结果是在 Visual Studio Community 2019 中编译此代码。

【问题讨论】:

  • 这对我来说根本不是“可以理解的”。这肯定是个bug。 this 的所有用法都应该引用捕获,而不是编译器生成的 lambda 类,它对用户来说是不存在的。我无法使用g++ 9 进行复制(没有选项)。它打印4Bobo,就像@songyuanyao 的测试一样。
  • 无法使用clanggcc 进行复制。你的编译器是什么?
  • @songyuanyao 我在 Windows 上使用 Visual Studio Community 2019 编译。我再次检查,这就是我得到的结果。通过创建一个局部临时变量并捕获它,我得到了我想要的行为。不过,这不应该发生吗?
  • 不,这是错误的。请提交一个针对 VS 的错误 :-)

标签: c++ visual-studio visual-c++ lambda capture


【解决方案1】:

这似乎是 VS 的错误;在判断lambdathis指针的类型时:

对于name lookup,确定类型和值 this pointer 和访问非静态类成员,主体 在上下文中考虑闭包类型的函数调用运算符 的 lambda 表达式。

struct X {
    int x, y;
    int operator()(int);
    void f()
    {
        // the context of the following lambda is the member function X::f
        [=]()->int
        {
            return operator()(this->x + y); // X::operator()(this->x + (*this).y)
                                            // this has type X*
        };
    }
};

所以this的类型在lambda中应该是Bobo*

【讨论】:

    【解决方案2】:

    正如@songyuanyao 建议的那样,您应该可以工作并生成适当的typeid,所以这可能是一个错误。但是 - 这里有一个解决方法:

    #include <iostream>
    
    class Bobo
    {public:
        int member;
        void function() {
            auto lambda = [this]() { std::cout << member << '\n'; };
            auto lambda2 = [my_bobo = this]() { 
                std::cout << typeid(std::decay_t<decltype(*my_bobo)>).name() << '\n'; 
            };
            lambda();
            lambda2();
        }
    };
    
    int main() {
        Bobo bobo;
        bobo.function();
    }
    

    请注意,您可以将typeid(...).name() 替换为正确的类型名称,根据this answer 获得(在编译时!):

    std::cout << type_name<std::decay_t<decltype(*my_bobo)>>() << '\n'; 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-02
      • 1970-01-01
      相关资源
      最近更新 更多