Search code examples
c++templatesenable-if

compile error - templates, enable_if


could you tell me why this code doesn't compile?

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);
}

What am I missing?

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

Solution

  • You declare Citizen to be a class template taking 5 template parameters:

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

    and then try to define the constructor using only 4 template parameters:

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

    There is no such previously declared 4-template-parameter Citizen, hence the error. You still need that last template parameter.


    Note that SFINAE here doesn't make much sense unless you have some other non-arithmetic Citizen class template (which itself doesn't make much sense). Just have a static_assert for T being an arithmetic type.