Как я могу получить доступ к `typeid` захваченного указателя this в лямбде? - PullRequest
2 голосов
/ 17 июня 2020

У меня такой код:

#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 << typeid (* this) .name (); in lambda2 () по понятным причинам выводит: </p>

class <lambda_49422032c40f80b55ca1d0ebc98f567f>

Однако как я могу получить доступ к указателю 'this', который был захвачен, чтобы оператор typeid мог возвращать тип класса Bobo?

Изменить: результат Я получаю это от компиляции этого кода в Visual Studio Community 2019.

Ответы [ 2 ]

1 голос
/ 17 июня 2020

Похоже, это ошибка VS; при определении типа this указателя в лямбда :

В целях поиска имени , определение типа и значения этот указатель , а для доступа к нестатическим c членам класса тело оператора вызова функции закрывающего типа рассматривается в контексте лямбда-выражения.

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 должен быть Bobo* в лямбде.

0 голосов
/ 17 июня 2020

Как предлагает @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() на правильное имя типа, полученное (во время компиляции!) В соответствии с этим ответом :

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