如何使用默认参数等选择模板专业化

How are template specializations chosen with default arguments and more

本文关键字:专业化 选择 何使用 默认 参数      更新时间:2023-10-16

https://stackoverflow.com/a/22487113/4416169在下面的答案中,我们可以看到仔细检查的代码:

#include <iostream>
#include <type_traits>
template <typename T, T N, typename = void > 
struct X {
static const bool isZero = false;
};
template <typename T, T N>
struct X < T, N, typename std::enable_if<N == 0>::type > {
static const bool isZero = true;
};
int main(int argc, char* argv[]) {
std::cout << X <int, 0>::isZero << std::endl;
std::cout << X <int, 1>::isZero << std::endl;
return 0;
}

https://stackoverflow.com/a/35652391/4416169在这里我们可以看到模板是如何选择的:

选择模板专业化需要五个步骤:

  1. 获取主模板声明
  2. 填写用户指定的模板参数
  3. 函数模板only:推导额外的模板参数
  4. 使用默认值剩余的模板参数
  5. 使用部分排序算法(C++14 14.5.6.2(选择最佳匹配专业化

首先,我知道SFINAE将负责排除std::enable_if<N==0>当N!=0。自N=0总是导致选择以前定义的模板(非专用模板(,我想知道为什么N=0选择了最近定义的模板,而不是前者。因此,遵循这些步骤,我们可以进一步仔细检查(在T=int和N=0的情况下(:

  1. 模板<typename T,T N,typename=无效>
  2. T是int,N是0;模板<int,0,(未命名类型(>
  3. 什么都不做我们不是一个函数
  4. (未命名类型(无效;模板<int,0,void>
  5. 对此进行了解释:https://stackoverflow.com/a/17008568/4416169

我们现在知道,当我们试图访问X<int,0>:isZero有两个选项,一个默认情况下将默认模板类型设置为void,另一个则将相同的模板类型设为void,但不是默认情况下,而是显式设置。

  • 编译器是否总是喜欢参数最少的模板(在所有可用的模板专业化中(?

  • 此外,正在扩展:这是否意味着选择具有最少实际参数的模板,而不是具有相同数量的显式参数(显式参数与非默认或强制性参数相同(但剩余部分设置为默认值的模板?

更清楚地说:

template<typename T, T N, typename C = void>
struct defTempArgStruct {
static constexpr unsigned int value = 0;
};
template<typename T, T N>
struct  defTempArgStruct<T,N>
{
static constexpr unsigned int value = 99;
};

int main()
{
std::cout << defTempArgStruct<int, 2>::value << std::endl;
}

为什么代码选择第二个专用模板(<typename T,T N>(,显示99,而不是第一个?为什么它选择第一个,显示0,而第二个,专门的,一个变为:

template<typename T, T N>
struct  defTempArgStruct<T,N,float>
{
static constexpr unsigned int value = 99;
};

非常令人困惑。

请急于纠正任何我做错的地方

一个可行的部分专业化总是优先于主模板:

[temp.class.spec.match]/1当在需要实例化类的上下文中使用类模板时,有必要确定是使用主模板还是部分专业化之一来生成实例化。这是通过将类模板专业化的模板参数与部分专业化的样板参数列表进行匹配来完成的。

(1.1(-如果正好找到一个匹配的专门化,则实例化将从该专门化生成
(1.2(-如果找到多个匹配的专业化,则使用偏序规则(17.5.5.2(来确定其中一个专业化是否比其他专业化更专业。如果没有一个专业化比所有其他匹配的专业化更专业化,那么类模板的使用是不明确的,并且程序格式不正确
(1.3(--如果没有找到匹配项,则从主模板生成实例化。