【C++】可変引数テンプレートの型がすべて同じ型であることをチェックするメタ関数

C++,小ネタ

可変引数テンプレートを使うと可変長引数を持つ関数を実装できます。

template <typename... Types>
void func(Types... types)
{
    ...
}

このとき、引数の型がすべて同じ型であることをチェックしたいと思い、メタ関数を作成してみました。

実装

#include <type_traits>

template <typename T, typename... Types>
struct is_all_same {
    using type = std::true_type;
    static constexpr bool value = type::value;
};

template <typename T1, typename T2, typename... Types>
struct is_all_same<T1, T2, Types...> {
    using type = std::false_type;
    static constexpr bool value = type::value;
};

template <typename T, typename... Types>
struct is_all_same<T, T, Types...> {
    using type = typename is_all_same<T, Types...>::type;
    static constexpr bool value = type::value;
};

C++17以降であれば、std::conjuntion<>メタ関数が追加されており、パラメータパックの展開と合わせてかなりシンプルに書けます。

template <typename T, typename... Types>
struct is_all_same : std::conjunction<std::is_same<T, Types>...> {};

参考

使い方

可変引数テンプレートを使った関数/クラスの中で、static_assert()を使いチェックします。

#include <cassert>

template <typename... Types>
void func(Types... args)
{
    static_assert(is_all_same<Types...>::value, "All arguments must be of the same type.");
}

C++,小ネタ

Posted by izadori