【问题标题】:Templates: SFINAE specialization not getting applied模板:SFINAE 专业化未得到应用
【发布时间】:2017-01-10 18:05:39
【问题描述】:

至少我认为下面的 sn-p 是 SFINAE 应用于专业化的一个尽可能简单的例子。

最后一行是重点,也是发生故障的地方。专门的foo 模板的定义决定了bar 模板的专门化,或者我想要的。其他 bar 特化可以在别处定义,或者可能不支持使用任意类型。

据我了解,广泛建议将相同的模式用于enable_if

template <typename T>
struct foo;

template <>
struct foo<int> {
  using type = int;
};

template <typename T, typename use = void>
struct bar;

template <typename T>
struct bar<T, typename foo<T>::type> {
  using type = typename foo<T>::type;
};

using good = typename foo<int>::type;
using bad = typename bar<int>::type; 

在 g++ 中,使用 14 或 17 标准,结果如下所示。似乎没有应用 bar 特化,编译器正在使用非特化(空)定义。为什么?

$ g++ --std=c++14 special.cpp -o special
special.cpp:18:32: error: ‘type’ in ‘struct bar<int>’ does not name a type
 using bad = typename bar<int>::type;

【问题讨论】:

  • bar&lt;int, foo&lt;int&gt;::type&gt; &lt;==&gt; bar&lt;int, int&gt; bar&lt;int, void&gt; != bar&lt;int, int&gt;
  • 您正在实例化bar&lt;int, void&gt;。为什么您希望编译器使用除“空”定义之外的任何其他内容?您对 bar 的“非空”特化甚至远程匹配 &lt;int, void&gt; 参数。

标签: c++ templates sfinae specialization


【解决方案1】:
template <typename T>
struct bar<T, typename foo<T>::type> {
  using type = typename foo<T>::type;
};

应该是

template <typename T>
struct bar<T, std::void_t<typename foo<T>::type>> {
  using type = typename foo<T>::type;
};

use 应始终为 void

这就是为什么命名为AlwaysVoid 会更好。 (或将其角色用作Enabler

template <typename T, typename AlwaysVoid = void>
struct bar;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-03
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多