N4567 14.5.5.1 [temp.class.spec.match] p4
在引用类模板特化的类型名称中,(例如,A)参数列表应该 匹配主模板的模板参数列表。 专业化的模板参数是从主模板的参数推断出来的。
template<class T1, class T2, int I> class A { }; // #1
template<class T, int I> class A<T, T*, I> { }; // #2
A<int, int, 1> a1; // uses #1
这“推断”是否意味着14.8.2.5 [temp.deduct.type]?
模板参数可以在几个不同的上下文中推导出来,但在每种情况下,根据模板参数(称为
P
)指定的类型与实际类型进行比较(称之为A
),并且尝试在替换之后查找将生成P
的模板参数值(类型参数的类型,非类型参数的值或模板参数的模板)。推导出的值(称之为推导出的A),与A兼容。
如果是,那么P和A是什么?
专业化的模板参数意味着 主要模板的实际模板参数 {{1} 或 部分专业化 int, int, 1
或其他的模板参数?
主要模板的参数表示主要模板的实际模板参数 T, T*, I
或 主模板的隐式模板参数 int, int, 1
或其他?
这句话是什么意思?
更新
看起来@Igor Tandetnik和@R Sahu有不同的答案,我需要更多的帮助。
答案 0 :(得分:0)
首先,应该注意these rules更像是在实现C ++解析器(如编译器),所以如果不满足其中一个特定规则,那么程序应该是非符合(和生成的错误)。所以你在段落中提到:
在引用类模板特化的类型名称中(例如,
A<int, int, 1>
),参数列表应与主模板的模板参数列表匹配。专业化的模板参数是从主模板的参数中推导出来的。
认为它意味着如果被解析的源不符合这些段落的限制,则它是不符合的,因此产生错误。
直接回答主要问题:
什么“专业化的模板参数是从主要模板的参数中推断的”是什么意思?
14.5.5
是关于模板部分特化,14.5.5.1
专门用于匹配部分特化和第4段(句子来自)只是说传递给模板的模板参数必须匹配那些一个专门的模板。
第4段的最后一句(有问题的一句),只是说传入的论据是根据主要模板推断出来的。
在讨论此段落时,它给出了A<int, int, 1>
的示例,并且它引用了14.5.5.1
中给出的示例中的其他模板特化(为便于阅读而分开):< / p>
// #1 (main template)
template<class T1, class T2, int I>
class A
{ };
// #2
template<class T, int I>
class A<T, T*, I>
{ };
// #3
template<class T1, class T2, int I>
class A<T1*, T2, I>
{ };
// #4
template<class T>
class A<int, T*, 5>
{ };
// #5
template<class T1, class T2, int I>
class A<T1, T2*, I>
{ };
所以,给出以下代码:
A<int, int, 1> a1;
A<int, char*, 5> a2;
A<int, int, 2.0f> a3;
A<int*> a4;
a1
编译正常,将使用模板#1
(因为它与该特化完全匹配),因此模板#1
将编译为以下内容:
template<
class T1 = int,
class T2 = int,
int I = 1>
class A
{ };
a2
也可以正常编译,模板#4
将被用作:
template<
class T = char>
class A<int, T*, 5>
{ };
但是, a3
并不匹配任何模板特化,并且编译a3
时符合标准的编译器会生成错误,因为int
的类型不匹配类型float
;也就是说,a3
会生成以下类型的模板:
template<
class T1 = int,
class T2 = int,
int I = 2.0f>
class A
{ };
因此,int
不是float
,因此应该生成错误。最后,a4
也不会编译,因为它只有1个模板参数,而A
的所有模板特化都需要3个参数。
继续提问:
这是&#34;推断&#34;平均值14.8.2.5 [temp.deduct.type]?
是和否,deduced
指的是整个14.8.2 Template argument deduction
,其中第2段指出:
当指定显式模板参数列表时,模板参数必须与模板参数列表兼容,并且必须产生有效的函数类型,如下所述;否则类型扣除失败。
described below
为了简洁而在此处发布了额外的积分。
但是,14.8.2.5
具体指的是如何以符合的方式推断出类型,如果模板专业化不能以这种方式推导出来,那么它应该失败(即编译器应该生成错误。)
如果是,那么P和A是什么?
此句中的P
和A
只是占位符值,可用于文本的其余部分。
特别是它试图获得的是P
表示模板参数,A
表示可以使用的实际类型,如{{1} }或int
或用户定义的类型,例如std::string
,class
或struct
或函数。
以此代码为例:
typedef
在此代码中,#1
template < class T >
struct A {
T val;
};
#2
template<>
struct A<double>
{
double val;
};
int main() {
A<int> a1; // uses #1
A<double> a2; // uses #2
A<someVal> a3; // uses #1 but generate error since `someVal` is invalid type
}
val将是P
的模板参数,class T
val将A
int
a1
double
} a2
和someVal
a3
。符合标准的编译器应该为a3
生成错误,因为没有类型that will make P, after substitution of the deduced values (call it the deduced A), compatible with A
,因为someVal
不是有效类型。
使用上面的示例A<int, int, 2.0f> a3;
,因为没有定义可以采用最后一个参数的模板(2.0f
),这里的P
val是int
并且A
val是2.0f
;由于2.0f
不是int
,因此此模板推断失败并生成错误。
您还问:
专门化的模板参数是指主模板int,int,1的实际模板参数还是部分特化T,T *,I或其他的模板参数?
The template arguments of a specialization
指的是传递给模板的参数,因此在A<int, int, 1>
中,此专精的模板参数为int
,int
和1
。
主模板的参数是指主模板int,int,1的实际模板参数,还是主模板T1,T2,I或其他模板的隐式模板参数?
the arguments of the primary template
指的是主要模板本身,因此在上面的A
示例中,主要模板为template<class T1, class T2, int I> class A { };
我希望可以提供帮助。
答案 1 :(得分:-1)
鉴于您的模板及其专业化,使用:
A<int, int*, 1> a2;
将使用专业化。
对于这种用法,
主要模板的模板参数为int
,int*
和1
。
模板特化的模板参数为int
和1
。
专业化的参数int
和1
是从主要模板int
,int*
和1
的参数中推断出来的。< / p>
在这种情况下,
P
是int
,int*
和1
A
是专业化。
我认为这就是你要找的答案。