2016-11-30 4 views
1

このコードがコンパイルされない理由を教えてください。コンパイルエラー - テンプレート、enable_if

template <typename T, T minAge, T maxAge, bool isarmed, 
typename = std::enable_if_t<std::is_arithmetic<T>::value>> 
class Citizen { 
public: 

    Citizen(T health, T age); 
    Citizen(T health, T age, T attackPower); 
    T getHealth() const { return _health; }; 
    T getAge() const { return _age; }; 
    T getAttackPower(); 
    void takeDamage(T damage); 

private: 
    T _health; 
    T _age; 
    T _attackPower; 
}; 

template <typename T, T minAge, T maxAge, bool isarmed> 
Citizen<T, minAge, maxAge, isarmed>::Citizen(T health, T age): 
     _health (health), 
     _age (age) 
{ 
    static_assert(minAge <= maxAge, "Wrong age"); 
    assert(minAge <= this->_age && this->_age <= maxAge); 
} 

何が欠けていますか?

error: invalid use of incomplete type ‘class Citizen<T, minAge, maxAge, isarmed>’ 
+0

誤解されていない場合、SFINAEは関数テンプレートのオーバーロード解決に使用されます。私はあなたがクラステンプレートのためにそれを使用できるとは思わない。 –

+0

@RSahuそれは可能です。それは[void_t'のしくみ]です(@stackoverflow.com/q/27687389/2069064) – Barry

+0

@Barry、リンクありがとうございます。私はまだSFINAEに関して私の基礎を真っ直ぐにしています。 –

答えて

3

あなたは5つのテンプレートパラメータを取ってクラステンプレートであることをCitizenを宣言します。その後、

template <typename T, T, T, bool, typename > 
class Citizen { ... }; 

のみ4テンプレートパラメータを使用してコンストラクタを定義しよう:

template <typename T, T minAge, T maxAge, bool isarmed> 
Citizen<T, minAge, maxAge, isarmed>::Citizen(T health, T age) 

なしありそのような以前に宣言された4テンプレートパラメータCitizen、したがってエラー。それでも最後のテンプレートパラメータが必要です。あなたは(それ自体はあまり意味がありません)他のいくつかの非算術Citizenクラステンプレートを持っていない限りSFINAEがここにあまり意味がありません


注意。算術タイプのの場合はstatic_assertとしてください。

+0

今、2つのシナリオでCtorを宣言したい場合はどうすればいいですか? 1つはisarmed == trueと反対ですか? – tomtom

+0

5番目のテンプレートパラメータにはデフォルトのタイプがあります。コンパイラが最初のテンプレートパラメータからそれを派生させないのはなぜですか? –

+0

@RSahuデフォルトがあります。これは、ユーザーがデフォルトではないものを提供できないという意味ではありません。 – Barry

関連する問題