不要对template-parameter-list中语法中的class关键字感到困惑。也就是说,那里的关键字并不表示实际的类(甚至没有给定名称的类),而是将在模板参数列表中推导或指定的类型的名称。或者,(我更喜欢),您可以使用关键字,它可以更好地表达其含义:class ClassBclasstypename
那是:
template <class T, class ClassB> void func(ClassA<T> obj1, ClassB obj2)
等于:
template <typename T, typename ClassB> void func(ClassA<T> obj1, ClassB obj2)
范围内的ClassB名称会影响声明。在函数的范围内,这是在模板参数列表中推导或指定的类型的名称。也就是说,它实际上可以是任何东西:funcclass ClassB
func(ClassA<int>{}, 123); // ClassB is now deduced to be int
func(ClassA<int>{}, 3.14); // ClassB is now deduced to be double
func(ClassA<int>{}, 'A'); // ClassB is now deduced to be char
func<int, long long>(ClassA<int>{}, 5); // ClassB is specified to be long long
还有一个说明阴影的例子:
template <class T, class ClassB> void func(ClassA<T> obj1, ClassB obj2)
{
ClassB a; // a has the deduced or specified type
::ClassB<int> b; // b has the true ClassB<int> type
}
最后,上面的声明和下面的声明的区别:
template <class T> void func(ClassA<T> obj1, ClassB<T> obj2)
是在后一种情况下,func接受ClassA实例和ClassB实例具有相同的类型参数,而第一个声明,如前所述,可以匹配任何类型作为第二个。
换句话说,在第一个例子中,模板实参推导机制对于第一个参数的类型被限制为只推导声明中的类型,而T在ClassA<T>推导第二个参数的类型时不受任何限制。