【问题标题】:A template class that only accepts enum type arguments?只接受枚举类型参数的模板类?
【发布时间】:2021-01-08 16:04:54
【问题描述】:

给定这个伪存根类:

template<class T>
MyClass
{
 std::map<T,std::string> mContents;
};

有没有办法只允许T 成为枚举类型?我试图了解这个问题和链接页面中讨论的内容,我是否可以使用std::enable_ifstd::is_enum,但我无法轻易理解它是否适​​合我的情况(Template specialization for enum

【问题讨论】:

  • static_assert(std::is_enum&lt;T&gt;::value, "not an enum"); 意义上的“力”?
  • @JHBonarius 应该将关于模板函数和模板类的大致相同问题视为重复项吗?如果是,那么这是一个骗局 - 谢谢
  • 虽然通过使用 C++20 约束或enable_if 等来“对 SFINAE 友好”,但对于函数模板来说比对类模板更重要。它仍然可以对类模板产生影响,但其他模板代码检测/依赖于类模板特化是否有效的情况要少得多。

标签: c++ c++11


【解决方案1】:

您不需要任何enable_if 技巧。你只需要一个static_assert:

template<class T>
class MyClass
{
  // pre-C++17:
  static_assert(std::is_enum<T>::value, "template argument must be enum");
  // C++17
  static_assert(std::is_enum_v<T>);
  std::map<T,std::string> mContents;
};

在 C++20 中,您可以改用约束。

【讨论】:

  • 以前没遇到过,谢谢
  • @dyp C++Reference 说它甚至是 C++17。进行了编辑。
  • 对,is_enum_vstatic_assert 有一个表达式是 C++17。 C++20 约束可能看起来像 template &lt;class T&gt; requires std::is_enum_v&lt;T&gt; class MyClass...
  • @Mr.Boy 我更喜欢static_assert,如果可能的话。静态断言更好地显示意图,因为它总是一个硬错误,而enable_if 也可以用于 SFINAE。它还使您可以选择指定一个清晰易懂的编译错误,而不是使用 enable_if 的失败实例化生成的模板错误页面。
  • @Mr.Boy 首先,enable_if 在 Marek 的回答中是误用,因为它实际上并没有禁用专业化。此外,比较两种方法的失败案例中的错误消息,您会发现巨大的差异。
【解决方案2】:

https://godbolt.org/z/4bvdrb

template<class T, typename = std::enable_if_t<std::is_enum_v<T>>>
class MyClass
{
    std::map<T,std::string> mContents;
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 2018-01-29
    相关资源
    最近更新 更多