テンプレートの偏特化によるコンパイル期間の断言

4290 ワード

テンプレートの偏特化によるコンパイル期間の断言
C/C++言語での役割は目に見えますが、実行期間でしか機能しないと断言し、コンパイル期間中に条件をチェックし、成立しないとコンパイルエラー情報を生成したい場合があります.例えば、テンプレートを書いたが、テンプレートのパラメータは整数タイプしかないことを望んでいます.他のタイプでテンプレートをインスタンス化するときは、コンパイルに通じないようにしてください.どうですか.かっこいいですね.
テンプレートの偏特化を利用して、軽くゆるめて実作することができます.
template<bool>
compile_assert;

template<>
compile_assert<true>{};

いいえ、このテンプレートはパラメータがtrueの場合にのみ偏特化されています.パラメータfalseを使用してcompile_assertをインスタンス化すると、定義されていないタイプのコンパイルエラーが発生します.簡単でしょ?
どのように使うかを見てみましょう.それとも前に述べた例を見て、テンプレートを書いたとします.テンプレートパラメータはint longと様々な修飾子(unsigned constなど)を加えて生成されたタイプのセットのいずれかのタイプしかパラメータにならないことを望んでいますが、他のタイプを使用している場合はコンパイルできません.
template<class IntType>
class need_int_type{ /* some code */ };

目的を達成するには、まず条件を書いて、与えられたタイプが整数タイプであるかどうかを判断する必要があります.
template<class Type>
struct is_int_type
{
    enum{ value = 0}
};

このテンプレートをint longに特化することができます.
template<>
struct is_int_type<int> { enum{ value = 1} };

template<>
struct is_int_type<long> { enum{ value = 1} };

unsignedまたはconstまたはこれらの修飾子を参照して修飾するタイプについては、裸のタイプと同じであるべきです.
template<class Type>
struct is_int_type<unsigned Type>
{
    enum{ value = is_int_type::value }
};

template<class Type>
struct is_int_type<const Type>
{
    enum{ value = is_int_type::value }
};

template<class Type>
struct is_int_type
{
    enum{ value = is_int_type::value }
};

次に、この判断結果を自分のテンプレートに渡すには、テンプレートパラメータを追加する必要があります.
template<class Type, int IsInt>
class only_for_int;

template<class Type>
class only_for_int<Type, 1>{};

このテンプレートは、2番目のパラメータが1の場合に偏特化されています.0を2番目のパラメータとして定義していない場合は、自分のテンプレートを継承すればいいのです.
template<class Type>
class need_int_type 
   : private only_for_int<Type, is_int_type<Type>::value>
{
   /* some code */
};