模板:未申请 SFINAE 专业化

Templates: SFINAE specialization not getting applied

下面的代码片段,至少我认为,是 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;
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;