【问题标题】:compile error - templates, enable_if编译错误 - 模板,enable_if
【发布时间】:2016-11-30 18:22:17
【问题描述】:

你能告诉我为什么这段代码不能编译吗?

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>’

【问题讨论】:

  • 如果我没记错的话,SFINAE 是用于函数模板的重载解析。我认为你不能将它用于类模板。
  • @RSahu 当然可以。那是how void_t works
  • @Barry,感谢您的链接。我还没有弄清关于 SFINAE 的基本知识。

标签: c++ templates enable-if


【解决方案1】:

您将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-template-parameter Citizen,因此出现错误。您仍然需要最后一个模板参数。


请注意,这里的 SFINAE 没有多大意义,除非你有一些其他非算术 Citizen 类模板(它本身没有多大意义)。只需将static_assert 用于T 是一种算术类型。

【讨论】:

  • 现在,如果我想为 2 个场景声明 Ctor 怎么办。一个代表 isarmed == true 而相反?
  • 第五个模板参数有一个默认类型。为什么编译器不会从第一个模板参数派生它?
  • @RSahu 有一个默认值。这并不意味着用户不能提供非默认值。
  • 那么,为什么Citizen&lt;T, minAge, maxAge, isarmed&gt;::Citizen(T health, T age) 有问题?
  • @RSahu 因为Citizen 不采用 4 个模板参数。需要5个。这里没有模板实例化。
猜你喜欢
  • 1970-01-01
  • 2012-12-07
  • 2015-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多