什么“专业化的模板参数是从主模板的参数中推导出来的”是什么意思?

时间:2015-12-31 22:19:50

标签: c++ templates language-lawyer

  

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有不同的答案,我需要更多的帮助。

2 个答案:

答案 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是什么?

此句中的PA只是占位符值,可用于文本的其余部分。

特别是它试图获得的是P表示模板参数,A表示可以使用的实际类型,如{{1} }或int或用户定义的类型,例如std::stringclassstruct或函数。

以此代码为例:

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 } a2someVal 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>中,此专精的模板参数为intint1

  

主模板的参数是指主模板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;

将使用专业化。

对于这种用法,

主要模板的模板参数为intint*1
模板特化的模板参数为int1

专业化的参数int1是从主要模板intint*1的参数中推断出来的。< / p>

在这种情况下,

Pintint*1 A是专业化。

我认为这就是你要找的答案。