This question already has answers here:
How does `void_t` work

(2 个回答)


2年前关闭。




我有一个程序如下。有一个基本模板 struct X 和 SFINAE 的部分特化。
template <typename T, typename U = void>
struct X{
  X() {
    std::cout << "in 1" << std::endl;
  };
};

template <typename T>
struct X< T, std::enable_if_t<std::is_integral_v<T>> > {
  X() {
    std::cout << "in 2" << std::endl;
  };
};

int main() {
  X<int> x;
}

运行程序时会打印 in 2
  • 为什么选择第二个特化而不是第一个特化,因为它们都有效地声明了 struct X<int, void> 。是什么让 std::enable_if_t<std::is_integral_v<T>> 比基本模板中显示的默认模板类型参数更专业?
  • 为什么基本模板的默认类型参数必须与部分特化定义的类型相同才能调用部分特化并打印 in 2
    为什么更改为 std::enable_if_t<std::is_integral_v<T>, bool> 会导致调用基本模板 in 1
  • 最佳答案

    您的问题的答案在于 o​​jit_a 。这是编译器用来确定哪个模板最适合的机制(无论是函数模板重载,还是在您的情况下,是类模板特化)。

    简而言之,您的通用模板实现有 2 个参数 TU ,而您的 SFINAE 特化只有 T 参数,而第二个参数是从 T 推导出来的。因此,它比一般情况更专业,最后,当您引用 X<int, void> 时,会选择特化。

    现在是问题 2。假设我们将 enable_if 参数替换为 bool 而不是 void 。现在我们的特化将是 X<int, bool> 而不是 X<int, void> ,所以当你提到 X<int> ,即 X<int, void> 时,它​​不再匹配特化,因为它们是 2 种不同的类型。

    关于c++ - 具有默认参数的模板特化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51479015/

    10-13 08:13