Как быть явным о типе захваченной переменной в лямбде? - PullRequest
1 голос
/ 26 мая 2019

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

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

Я узнал, что могу использовать std::tuple для этого, как показано ниже, но мне интересно, есть ли более лаконичный способ.

template<typename T>
auto returns_functor (T&& value)
{
  return [value = std::tuple<T> (std::forward<T> (value))] ()
  {
    /* use std::get<0> (value) */
  };
}

Связанный: Захват идеально переадресованной переменной в лямбде (принятый там ответ предполагает, что это другой вопрос, но дальнейшие ответы дают, по существу, вышеуказанное решение).

1 Ответ

0 голосов
/ 28 мая 2019

Другой способ захвата rvalue (универсальная ссылка) заключается в следующем:

template< typename T>
T getRvalue( T&& temp)
{
  auto lambda = [ rTemp = std::move( temp)]() mutable
  {
     return T( std::forward< T>( rTemp));
  };

  return lambda();
}

std::move() позволяет захватывать объекты подвижного типа, которые не могут быть захвачены копией.mutable очень важно здесь в лямбде, пока mutable не используется, объекты, захваченные лямбдой, не могут быть изменены, и компиляция выдаст следующую ошибку,

cannot conver 'rTemp (type 'const T') to type 'std::remove_reference<T>::type&' {aka 'T&'}
return T( std::forward< T>( rTemp));

Теперь о первом вопросе, «Как я могу явно указать тип захваченной переменной для лямбды в C ++?» Так что указывать тип не обязательно, компиляция сделает это, см. Следующую ссылку,https://en.cppreference.com/w/cpp/language/lambdaВ нем говорится A capture with an initializer acts as if it declares and explicitly captures a variable declared with type auto, whose declarative region is the body of the lambda expression. Проще говоря, это означает, что автоматическая переменная выводится в соответствии с инициализатором и не требует явного указания ее типа, например

int x = 1;
auto lambda = [ y = x + 2](){ std::cout<< "y = "<< y<< std::endl;};

Здесь y будет выводиться как int инициализатором x + 2.

...