使用默认参数的模板特化

Rae*_*ani 3 c++ templates partial-specialization sfinae c++14

我有一个程序如下.有一个基本模板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;
}
Run Code Online (Sandbox Code Playgroud)

运行程序时in 2打印.

  1. 为什么第二个专业化被选为第一个专业化,因为它们都有效地声明了一个struct X<int, void>.什么 std::enable_if_t<std::is_integral_v<T>>比基本模板中显示的默认模板类型参数更专业?

  2. 为什么基本模板的默认类型参数必须与要调用和in 2打印的部分特化的部分特化定义的类型相同.为什么要更改以调用std::enable_if_t<std::is_integral_v<T>, bool>基本模板in 1

Rer*_*ito 5

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

总之,你的通用模板实现了2个参数TU,而你的SFINAE专业化仅有的T参数,而第二个是从推导T.因此,它比一般情况更专业,最后,当您提到时X<int, void>,选择专业化.

现在问题2.假设我们enable_ifbool而不是替换参数void.现在我们的专业化将X<int, bool>取代X<int, void>,所以当你提到时X<int>,即X<int, void>它不再与专业化相匹配,因为它们是两种不同的类型.