захватить переменную-член по значению - PullRequest
9 голосов
/ 15 сентября 2010

Как мне перехватить переменную-член по значению при использовании лямбда-выражений C ++ 11?

Использование синтаксиса [my_member], похоже, не работает, а неявный захват использует указатель this.Что нужно, так это способ явно указать тип захвата переменных-членов.Это возможно?

Мой обходной путь на данный момент:

void member_function()
{
    std::shared_ptr<my_member_class> my_member_copy = my_member; // this shouldn't be necessary
    std::async([=]{ std::cout << *my_member_copy; });
    // std::async([=]{ std::cout << *my_member_; }); // wrong, my member could be potentially out of scope
}

Ответы [ 5 ]

7 голосов
/ 15 сентября 2010

Я не думаю, что вы можете захватить член по значению, вы можете захватить this, но, поскольку член является частью this, вы будете использовать общий член, а не новую переменную.

Не зная, к какому типу относится ваш член, что-то вроде этого должно работать:

auto copy = my_member;
std::async([copy]{ std::cout << copy; });

Я не понимаю, почему вы используете shared_ptr в своем примере, если вы хотите захватить по значению, конечно, shared_ptr - последнее, что вы должны рассмотреть.

5 голосов
/ 01 марта 2012

К сожалению, я не думаю, что есть прямой способ сделать это, но я могу придумать пару способов захватить участника без создания дополнительной копии.

Первый вариант похож на ваш пример, но использует ссылку на локальную переменную:

void member_function()
{
   std::shared_ptr<my_member_class> &my_member_ref = my_member;
   // Copied by the lambda capture
   std::async([my_member_ref]{ std::cout << *my_member_ref; });
}

Обратите внимание, что в версиях GCC, предшествующих 4.6.2, имеется ошибка, из-за которой значение не копируется. См. Захват ссылочной переменной путем копирования в C ++ 0x лямбда .

Второй подход - использовать связывание для создания копии:

void member_function()
{
   // Copied by std::bind
   std::async(std::bind([](const shared_ptr<my_member_class>& my_member){
      std::cout << *my_member; }, my_member));
}

В этом примере bind создаст свою собственную копию my_member, и эта копия затем будет передана лямбда-выражению по ссылке.

4 голосов
/ 30 апреля 2015

Поскольку ваш вопрос касается C ++ 11, на самом деле это не ответ, но в C ++ 14 вы можете сделать так:

void member_function()
{
    std::async([my_member=my_member]{ std::cout << *my_member; });
}

Это делает то же самое, что и ваша собственная работа-around "(если my_member это shared_ptr).

1 голос
/ 17 мая 2017
auto& copy = my_member;
std::async([copy]{ std::cout << copy; });

auto & (выше) также работает и устраняет копирование дважды. Хотя этот подход является более синтаксическим, чем передача [this], он исключает передачу в замыкание зависимости, на которую указывает [this].

0 голосов
/ 30 октября 2011

Прямо сейчас я столкнулся с той же проблемой и решил ее сам:

  1. Захват указателя this.
  2. затем напишите this->member синтаксис внутри лямбды:

То есть

 std::async([this]{ std::cout << this->my_member_; } ); 
 //          ^^^^                ^^^^^^ use this syntax
 //           | 
 //           ^
 //           capture `this` as well

Это работает для меня. Я надеюсь, что это должно сработать и для вас. Однако я не совсем доволен этими знаниями. После работы я поищу причину, по которой этот синтаксис необходим, или это ошибка компилятора. Я использую GCC 4.5.0 (MinGW).

Ну, я нашел следующую тему, в которой говорится, что this указатель должен быть захвачен, чтобы использовать член класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...