C++ Lambda 표현식
작성일:
C++14, C++17, C++20 버전별 Lambda 표현 정리
The Evolutions of Lambdas in C++14, C++17 and C++20
- https://www.fluentcpp.com/2021/12/13/the-evolutions-of-lambdas-in-c14-c17-and-c20/
- 해당 글을 참고하여 예제 자체 작성
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
}
댓글남기기