【C++】可変長テンプレートの型比較を行う

#どんなの

こんな感じの処理をしてくれる関数が欲しい(模擬コード)

```cpp

template<typename... Type>
struct hoge{
	template<typename... Args>
	static constexpr bool hoge(){
		return Type == Args; //Type,Argsの型すべてに対して一致しているか確認
	}
};
```

つまるところ、可変長テンプレート型同士の型比較を行う関数が欲しいと言った所です。

現状上のようなソースコードを書いてしまおうものなら、目的が果たせないだけでなくコンパイラ様の怒りに触れ辺り一面(ターミナル)が焼け野原になってしまうので、
愛しの世界に平和をもたらす為に可変長テンプレート引数の比較を行えるラヴ&ピースなモジュールを作成しようと思いました。
なお、以下ソースコードはC++17を想定しています、

#作ったもの

※2019/7/2追記：コメントより、std::tupleで囲った方が簡潔に記述できるとのアドバイスを頂きました。
ありがとうございます！

```cpp
template<class ... B>
struct IsSame {
    using Base = std::tuple<B...>;

    template<class ... Comp>
    static inline constexpr bool isSame(){
        return std::is_same_v<Base,std::tuple<Comp ... > >;
    }
};
```

以下のソースコードは自分が書いた物です(アドバイス頂いたコードに比べると大分冗長なため、上のコードを使用することをお勧めいたします)

```cpp


#include <type_traits>

// >部分特殊化用
template <typename ... Args>
struct param;

// >比較処理に使用するクラス
namespace templatecmp{

    // >1次テンプレート
    template <typename... TypeList>
    struct cmp_check;

    // >引数が複数の時
    template <typename Now,typename... TypeList>
    struct cmp_check<param<Now,TypeList...>>{
		// 引数一つになるまで再帰的に宣言
        using ch = cmp_check<param<TypeList...>>;
        
		// 引数一つ or 型不一致 になるまで再帰呼び出ししつつ型チェックする
        template<typename T,typename... Args>
        static constexpr bool check(){
            return std::is_same_v<T,Now> ? ch::template check<Args...>() :  false;
        }
    };

    // >引数が一つ
    // テンプレート引数チェックの末尾
    template <typename Now>
    struct cmp_check<param<Now>>{
        template<typename... Args>
        static constexpr bool check(){
            return std::is_same_v<Args...,Now> ? true :  false;
        }
    };

    // >引数無し
    template<>
    struct cmp_check<param<>>{
        template<typename... Args>
        static constexpr bool check(){
            return sizeof...(Args) == 0;
        }
    };

};


// >可変長テンプレート引数比較クラス
template <typename... TargetTypeList>
struct cmp{

	// >比較処理に使用するクラス の型宣言
	// ここを入り口として、cmp_checkの中で再帰的に宣言されていく
    using ch = templatecmp::cmp_check<param<TargetTypeList...>>;

	// >テンプレート引数の比較関数
	// 上で再帰的に宣言されたクラスを使って、型比較の関数を再帰呼び出しする
    template<typename... Args>
    static constexpr bool check(){
        if constexpr(sizeof...(Args) == sizeof...(TargetTypeList)){ //サイズ不一致は弾く
            return ch::template check<Args...>();
        }else{
            return false;
        }
    }
};

```


使い方はこんな感じ(上のソースと連結した後iostreamのインクルード文を追加すれば確認できます)


```cpp
// >テストコード
class hoge{};
int main(){
    // >比較する型一覧の指定
    cmp<int,bool,float> ch;
    cmp<hoge,int> ch2;
    cmp<float> ch3;
    cmp ch4;

    // >比較対象を指定し比較
    std::cout << ch.check<int,bool,float>() << std::endl;
    std::cout << ch.check<hoge,int>() << std::endl;
    std::cout << ch.check<float>() << std::endl;
    std::cout << ch.check() << std::endl;
    std::cout << std::endl;

    std::cout << ch2.check<int,bool,float>() << std::endl;
    std::cout << ch2.check<hoge,int>() << std::endl;
    std::cout << ch2.check<float>() << std::endl;
    std::cout << ch2.check() << std::endl;
    std::cout << std::endl;

    std::cout << ch3.check<int,bool,float>() << std::endl;
    std::cout << ch3.check<hoge,int>() << std::endl;
    std::cout << ch3.check<float>() << std::endl;
    std::cout << ch3.check() << std::endl;
    std::cout << std::endl;

    std::cout << ch4.check<int,bool,float>() << std::endl;
    std::cout << ch4.check<hoge,int>() << std::endl;
    std::cout << ch4.check<float>() << std::endl;
    std::cout << ch4.check() << std::endl;
    std::cout << std::endl;
}

```

実行結果は以下の通り

```
1
0
0
0

0
1
0
0

0
0
1
0

0
0
0
1
```

#感想
・もっといい書き方が有りそう
・そもそも既に誰かが作ってそう
・そもそもそも気付いていないだけで既にSTLやboostに有ったりしたらどうしよ
・ターミナルだいすきうへへ

ソースコードに対する指摘、アドバイス、マサカリ、苦情、罵倒、暴言、世間話、その他諸々有りましたらコメントでご指摘いただけれるととても嬉しいです。
(特に当方メタプログラミングの経験が殆ど無いため、その点に関するご指摘など頂ければ非常に嬉しいです)

#参考にさせて頂いたサイト
[variadic templateで遊ぶ](https://in-neuro.hatenablog.com/entry/2016/12/05/000000)