2016-11-30 2 views
1

Не могли бы вы рассказать мне, почему этот код не компилируется?compile error - templates, 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'] (http://stackoverflow.com/q/27687389/2069064) – Barry

+0

@Barry, спасибо за ссылку. Я еще не понял свои основы относительно SFINAE. –

ответ

3

Вы объявляете Citizen быть шаблоном класса с 5 параметров шаблона:

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, следовательно, ошибка. Вам все еще нужен этот последний параметр шаблона.


Обратите внимание, что SFINAE здесь не имеет особого смысла, если у вас есть какой-то другой, не арифметический Citizen шаблон класса (который сам по себе не имеет смысла). Просто введите static_assert для T, являющегося арифметическим типом.

+0

сейчас, что, если я хочу объявить Ctor для 2 сценариев. Один для isarmed == true и наоборот? – tomtom

+0

Существует параметр по умолчанию для пятого параметра шаблона. Почему компилятор не выводит его из первого параметра шаблона? –

+0

@RSahu По умолчанию. Это не означает, что пользователь не может предоставить тот, который не является значением по умолчанию. – Barry