2016-12-15 14 views
1

は私がコンパイルし、期待通りに動作する最初のうち2つのコードセットを、持っているが、不必要に冗長に[なるように見える]されています。これは、私はむしろ書きたいコードがあるテンプレートを使用したテンプレートのメタプログラミング:最初のコードがコンパイルされ、2番目のコードがコンパイルされないのはなぜですか?

template<point_type type, typename T> 
struct point2d_base { 
    std::enable_if_t<std::is_arithmetic_v<T>, T> x, y; 
    template<point_type t2 = type> 
    point2d_base(std::enable_if_t<t2 == point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
    template<point_type t2 = type> 
    explicit point2d_base(std::enable_if_t<t2 != point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
/*Some unrelated code*/ 
}; 

が、私私はこのようにそれを行う場合、多くの、多くのコンパイルエラーを取得:genericcornercenter

参照便宜上
template<point_type type, typename T> 
struct point2d_base { 
    std::enable_if_t<std::is_arithmetic_v<T>, T> x, y; 
    point2d_base(std::enable_if_t<type == point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
    explicit point2d_base(std::enable_if_t<type != point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
/*Some unrelated code*/ 
}; 

は、point_typeは3つの値が含まれている「列挙型クラス」です。

私の質問は、なぜ最初のコードはコンパイルされ、2番目のコードはコンパイルされないのですか?

答えて

1

テンプレートクラスパラメータにstd::enable_ifを使用することはできません。 std::enable_ifに関数を使用する場合は、その関数をテンプレート関数にする必要があります。 クラステンプレートをインスタンス化すると、そのクラスのすべてのメンバー関数もインスタンス化されるからです。条件付きでその関数を有効にするかどうかを指定するには、テンプレートメンバー関数が必要です。 (私の推測で正しいと思います)

+0

2番目の例で書いたものに近い正しいバージョンのコードがあります。ここでは 'type'変数を次のように再宣言する必要はありません。何か? – Xirema

+0

'std :: enable_if'を使いたいと思うなら、そうは思わないでしょう。要件に基づくもう1つのオプションは、テンプレートの特殊化です。 – MRB

関連する問題