yohhoyの日記

技術的メモをしていきたい日記

ラムダ式のオーバーロード

プログラミング言語C++において、ラムダ式オーバーロード(もどき)を実装する方法。

// C++17
template <typename... Ts>
struct overloaded : Ts... {
  // 基底クラス(ラムダ式のクロージャクラス)が提供する
  // operator()群をoverloadedクラス自身から公開する
  using Ts::operator()...;
};

// テンプレート引数Ts...の推論ガイド宣言
template <typename... Ts>
overloaded(Ts...) -> overloaded<Ts...>;

// 文字列(const char*), doube型, それ以外でオーバーロード
auto printer = overloaded{
  [](const char* s) { std::cout << std::quoted(s) << '\n'; },
  [](double v) { std::cout << std::fixed << v << '\n'; },
  [](auto x) { std::cout << x << '\n'; }
};

printer("Hi");  // "Hi"
printer(3.14);  // 3.140000
printer(42);    // 42

C++17現在、集成体(aggregate)に対しては推論ガイド(deduction guide)の宣言が必要となる。(PDF)P1816R0採択によりC++2a(C++20)から推論ガイドが暗黙に生成されるようになる(C++17同様に明示宣言してもよい)。

// C++2a
template <typename... Ts>
struct overloaded : Ts... {
  using Ts::operator()...;
};
// 下記の推論ガイドが暗黙宣言される
// template <typename... Ts> overloaded(Ts...) -> overloaded<Ts...>;

関連URL