작성일:

C++14, C++17, C++20 버전별 Lambda 표현 정리

The Evolutions of Lambdas in C++14, C++17 and C++20


C++14

Default parameters

#include <iostream>
using namespace std;

int main()
{
  auto fn = [](int a, int b = 0) {
    return a + b;
  };

  cout << fn(1) << endl;     // 1
  cout << fn(1, 2) << endl;  // 3
}

Template parameters

#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
  auto fn = [](auto && c) {
    return c.size();
  };

  vector<int> v = {1, 2, 3};
  cout << fn(v) << endl;  // 3

  string s = "12345";
  cout << fn(s) << endl;  // 5
}

Generalised capture

#include <iostream>
#include <string>
using namespace std;

int main()
{
  string str = "string";

  auto fn = [s = str + "_capture"s](string body) {
    cout << s << " : " << body << endl; 
  };

  fn("test");  // string_capture : test
}

Returning a lambda from a function

#include <iostream>
using namespace std;

auto getAdd(int n)
{
  return [n](int an) {
    return n + an;
  };
}

int main()
{
  auto fn = getAdd(10);
  cout << fn(20) << endl;
}

C++17

Constexpr

#include <iostream>
using namespace std;

int main()
{
  constexpr auto fn = [](int n){
    return n + 10;
  };

  static_assert(fn(10) == 20); // ok
  static_assert(fn(20) == 20); // error: static assertion failed
}

Capturing a copy of *this

  • this 참조에 캡쳐가 아닌, *this 복사본 캡쳐
#include <iostream>
#include <memory>
#include <tuple>
using namespace std;

class item 
{
public:
  item(int n = 0) : _value(n) {}

  auto test() {
    _value += 1;

    // copy capture
    auto fn1 = [*this] { return _value; };
    auto fn2 = [self = *this] { return self._value; };

    // ref capture
    auto fn3 = [this] { return _value; };
    _value += 1;

    fn1(); // 11
    fn2(); // 11
    fn3(); // 12

    return make_tuple(fn1, fn2, fn3);
  }

private:
  int _value;
};

int main()
{
  auto it = make_shared<item>(10);
  auto tp = it->test();
  it.reset();

  cout << get<0>(tp)() << endl;
  cout << get<1>(tp)() << endl;
  cout << get<2>(tp)() << endl; // ref memory error 
}

C++20

Template syntax for lambdas

#include <iostream>
#include <vector>
using namespace std;

int main()
{
  auto fn = []<typename T>(vector<T> &v) { return v.size(); };

  vector<int> v = {1, 2, 3, 4, 5};
  cout << fn(v) << endl;
}

Lambda capture of parameter pack

#include <iostream>
#include <string>
using namespace std;

template <typename... Args>
auto getAddFunc(Args&&... args){
    // by ref    [&...args = std::forward<Args>(args)]
    // by value  
    return [...args = std::forward<Args>(args)] (auto && init) {
        return init + (args + ...);
    };
}

int main()
{
  auto fn = getAddFunc(1, 2, 3);
  cout << fn(10) << endl;  // 16

  auto fns = getAddFunc("this "s, "is "s, "sample"s);
  cout << fns("note: "s) << endl;  // note: this is sample
}

댓글남기기