スポンサーリンク
可変引数テンプレートもそうだが、if constexprやtype_traits、型推論に右辺参照もあるのでかなり簡単に書けるようになっている。
#include <iostream> #include <type_traits>
// 型TがArgs...に含まれているかどうかを判定するメタ関数 template <typename T, typename... Args> constexpr bool is_contains_type = (std::is_same_v<T, Args> || ...);
template<typename T, typename First, typename... Rest> decltype(auto) get_value(First&& first, Rest&&... rest) { if constexpr (std::is_same_v<T, std::decay_t<First> > == true) { return std::forward<First>(first); } // sizeof...(rest)で残りの引数の数をチェック else if constexpr (sizeof...(rest) > 0) { // 残りの引数restから T を探す return get_value<T>( std::forward<Rest>(rest)...); } else { static_assert(sizeof...(rest) > 0, "No matching type found in arguments."); } }
template <class... Args> void print(Args&&... args) { if constexpr (is_contains_type<int, std::decay_t<Args>...>) { auto&& arg_int = get_value<int>( std::forward<Args>(args)... ); std::cout << "int is " << arg_int << "\n"; } if constexpr (is_contains_type<double, std::decay_t<Args>...>) { auto&& arg_double = get_value<double>(std::forward<Args>(args)... ); std::cout << "double is "<< arg_double << "\n"; } if constexpr (is_contains_type<float, std::decay_t<Args>...>) { auto&& arg_float = get_value<float>(std::forward<Args>(args)... ); std::cout << "float is " << arg_float << "\n"; } }
int main() { print(1, 2.5, 5.f); // 引数が右辺値の場合 int K = 10; print(K); // 引数が左辺値の場合 std::cout << "K is " << K << "\n"; }