如何使用默认参数等选择模板专业化
How are template specializations chosen with default arguments and more
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在这里我们可以看到模板是如何选择的:
选择模板专业化需要五个步骤:
- 获取主模板声明
- 填写用户指定的模板参数
- 函数模板only:推导额外的模板参数
- 使用默认值剩余的模板参数
- 使用部分排序算法(C++14 14.5.6.2(选择最佳匹配专业化
首先,我知道SFINAE将负责排除std::enable_if<N==0>当N!=0。自N=0总是导致选择以前定义的模板(非专用模板(,我想知道为什么N=0选择了最近定义的模板,而不是前者。因此,遵循这些步骤,我们可以进一步仔细检查(在T=int和N=0的情况下(:
- 模板<typename T,T N,typename=无效>
- T是int,N是0;模板<int,0,(未命名类型(>
- 什么都不做我们不是一个函数
- (未命名类型(无效;模板<int,0,void>
- 对此进行了解释: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(--如果没有找到匹配项,则从主模板生成实例化。
- 如何使用默认参数等选择模板专业化
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 模板化建造师专业化
- 选择要调用的构造函数
- C++选择排序算法中的逻辑错误
- QTreeView幻灯片多选后无法使用单击选择
- 类模板的成员功能的定义在单独的TU中完全专业化
- 无法获取菜单选择以运行函数.C++
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 在C++中,如何通过几种类型从元组中选择多个元素
- 讨论 - 创建矩阵时的数组与向量的向量 - 什么是最实用的选择
- 对可变参数使用声明.如何选择正确的功能
- 选择选举获胜者的程序
- 部分专业化和嵌套模板
- enable_if如何帮助选择类模板的专业化?
- 为什么这个模板代码不选择部分专业化
- 为什么没有选择模板专业化?
- 使用声明类型选择函数专业化
- GCC 7 没有选择正确的类型特征专业化
- 是否可以使用std :: enable_if选择成员模板专业化