_Generic
C11から導入された機能。なんというか、色々と面白い事に使えそうな感じの機能。タプルなんかと多分相性が良い。曲芸的濫用についてはまた今度考える。
ラムダ式でオーバーロードする最も簡単な方法かもしれない。
http://melpon.org/wandbox/permlink/14pwv0Akg5DhrtnA
#include <iostream> int main() { auto f = [](auto arg) { std::cout << _Generic(arg, int: arg + 1, double: arg - 1.0, default: arg) << std::endl; }; f(1); f(1.5); }
複数の型の組み合わせで分岐したい場合、1つにまとめるとなんとかなる。
caseに当たる部分にはcomplete typeが要求され、tag<int, int>:と書いてもテンプレートのインスタンス化が行われずにコンパイルエラーになったが、delctype(tag<int, int>{}):とワークアラウンドを書いたところうまく動いた。
http://melpon.org/wandbox/permlink/WpLjU1hyNgcUERUX
#include <iostream> template <typename...> struct tag {}; template <typename T1, typename T2> auto f(T1 arg1, T2 arg2) { std::cout << _Generic(tag<T1, T2>{}, decltype(tag<int, int>{}): arg1 * arg2, decltype(tag<double, double>{}): arg1 * arg2) << std::endl; } int main() { f(3, 5); f(1.5, 2.0); }