至少我认为,下面的代码片段尽可能直接地将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;

在14或17标准的g++中,结果如下所示。似乎尚未应用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;

关于c++ - 模板:未应用SFINAE特化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41575468/

10-13 08:28