C ++ лямбда возвращает себя - PullRequest
       60

C ++ лямбда возвращает себя

0 голосов
/ 04 сентября 2018

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

Вот пример:

#include <iostream>

int main(int argc, char* argv[]) {
  int a = 5;
  [&](int b) {
    std::cout << (a + b) << std::endl;
    return *this;
  }(4)(6);
}

Есть ли способ сделать что-то сопоставимое?

Ответы [ 4 ]

0 голосов
/ 05 сентября 2018

Бен Фойгт предлагает использовать Y-комбинаторы (которые являются отличным предложением для стандартной библиотеки, кстати), но ваша проблема проще. Вы можете ввести небольшой шаблонный функтор, который будет вызываться вместо лямбды:

template<typename T>
struct recallable_impl {
    template<typename... Args>
    recallable_impl& operator()(Args&&... args) {
        f(std::forward<Args>(args)...);
        return *this;
    }

    template<typename F>
    recallable_impl(F&& f)
      :  f{std::forward<F>(f)}
    {}
private:
    T f;
};

template<typename T>
decltype(auto) recallable(T&& f) {
    return recallable_impl<std::decay_t<T>>(std::forward<T>(f));
}

Тогда вашей лямбде даже не нужно будет явно что-либо возвращать:

int main() {
  int a = 5;  
  recallable([&](int b){std::cout << (a + b) << std::endl;})(4)(5)(6)(7)(8);
}
0 голосов
/ 04 сентября 2018

со старым функтором:

int main() {
  int a = 5;
  struct S {
    const S& operator ()(int b) const {
      std::cout << (a + b) << std::endl;
      return *this;
    }
    const int& a;
  };
  S{a}(4)(6);
}

Демо

0 голосов
/ 05 сентября 2018

Вы можете вызвать лямбду, если назначите ее предопределенному типу (не авто), и она будет захвачена:

std::function<void(int)> f =[&f](int n)
{
    if (n>0) f(n-1);
    return;
};
0 голосов
/ 04 сентября 2018

Вы не можете вернуть саму лямбду, но вы можете вернуть другую:

#include <iostream>

int main() {
  int a = 5;    
  [&](int b) {
      auto impl = [&](int b){std::cout << (a + b) << std::endl;};
      impl(b);
      return impl;
  }(4)(6);
}

Тем не менее, это позволяет только вызвать его еще раз. Не уверен, что есть какая-то хитрость, чтобы извлечь из этого больше пользы ...

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