确定每次使用哪种模板专业结构
Deciding which template specialization structure to use each time
我在 C++
中有以下声明:
template<class T1, class T2> struct canAssign {
enum { result = false };
};
template<class T1> struct canAssign<T1,T1> {
enum { result = true };
};
我有以下电话(A
扩展了B
(:
canAssign<A,A>::result;
canAssign<B,A>::result;
canAssign<B*,A*>::result;
我知道它使用template specialization
功能,但我似乎不明白它如何决定每次选择哪一个?
编辑:我知道输出应该是什么:
true
false
false
我的问题是编译器如何选择合适的编译器?我需要在脑海中考虑哪种算法/方法/方法,以了解哪一种将被称为
可能的继承在这里不计数。
所以你有:
canAssign<A, A>::result; // true T1=A, T2=A as T1=T2, use specialization
canAssign<B, A>::result; // false T1=B, T2=A
canAssign<B*, A*>::result; // false T1=B*, T2=A*
我的问题是编译器如何选择合适的编译器?我需要在脑海中考虑哪种算法/方法/方法,以了解哪一种将被称为
该算法在您针对的特定标准的[temp.class.spec.match]部分(以及相关的算法(中进行了描述。
我的问题是编译器如何选择合适的编译器?我需要在脑海中考虑哪种算法/方法/方法,以了解哪一种将被称为
编译器选择最专业的版本(如果有歧义选择最专业的可用,并出现错误(。
当一个版本比另一个版本更专业
1(模板参数的所有匹配,对于更专业的匹配也是较少的专业
2(,并且有较少专业化的匹配,而不是更专业的
在您的情况下,您有两个版本的canAssign
:主要的和专业。
显然,专业化比主要版本更专业,因此,如果是
canAssign<A,A>::result;
机器人版本匹配,因此编译器选择专业化。
在其他情况下
canAssign<B,A>::result;
canAssign<B*,A*>::result;
仅主要版本匹配,因此编译器选择主版本。
一个更好地解释这一点的示例:假设您有一个带有两个专业的模板foo
template <typename, typename, typename>
struct foo
{ };
template <typename A, typename B>
struct foo<A, A, B>
{ };
template <typename A>
struct foo<A, A, A>
{ };
第二个专业化比拳头更专业。
实际上
1(所有集合参数(必然所有等于(匹配第二个模板参数,必须匹配第一个(第一个和第二个等于(
2(至少存在一组模板参数( int
, int
, long
(,与第一个相匹配,但不匹配第二个。
so:
1(第二个专业化比第一个专业化更专业
2(第一个专业化比主版本更专业
so
foo<int, int, int>
匹配所有版本,因此编译器选择第二个专业化foo<int, int, long>
匹配主版本和第一个专业化,因此编译器选择第一个专业化foo<int, long, int>
仅匹配主版本,因此编译器选择主版本。
这是一种模式匹配。
这将是一个恰好的故事。它与标准不完全匹配,但我发现它会产生良好的直觉。
template<class T1, class T2> struct canAssign {
enum { result = false };
};
这是主要的规格。它定义了模板签名-<class T1, class T2>
定义的两个类。如果没有其他匹配的话,它也是实例化的。
template<class T1> struct canAssign<T1,T1> {
enum { result = true };
};
这是次要专业。在这里,<class T1>
的目的不同。它引入了变量以匹配模式,而不是参数。
参数在<T1,T1>
部分中。编译器与传递的参数匹配<T1,T1>
。
"推论上下文"中的任何参数都是独立匹配的。因此,如果您通过<A,B>
,则与T1=A
匹配,然后T1=B
。这是不一致的;专业不匹配。如果通过<A,A>
,则与T1=A
和T1=A
匹配。这是一致的。
当您进行<T1*,T1*>
时,事情变得更加典型。然后,如果您通过<A,A>
,它将尝试T1*=A
并失败;但是,如果通过<A*,A*>
,它将以T1*=A*
开头,然后剥离*
并获取T1=A
,然后再次对第二个参数进行操作。
未建立的上下文是不同的。当您具有不循环的上下文(例如std::enable_if_t<some_bool, T1>
(时,该参数未完成模式匹配。取而代之的是,其他参数与模式匹配,然后将专业模板变量取代。如果结果类型与参数完全匹配,则它会通过。否则会失败。
最后一个位是订购。如果两个次要的专业经历通过,则严格"更专业"的胜利。如果两者都不具体专业化,则两者都不会获胜。更专业的规则很复杂;直观的想法是,一个专业化是否可以符合另一个案例,但反之亦然,严格匹配的一个专业化是更专业的。
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 没有为自己的结构调用列表推回方法
- 奇怪的结构&GCC&clang(void*返回类型)
- 在 c++ 中拥有一组结构的正确方法是什么?
- vscode g++链路故障:体系结构x86_64的未定义符号
- C++概念:如何使用'concept'检查模板化结构的属性?