模板函数和类

时间:2014-09-30 16:27:12

标签: c++ function-templates class-template

我真的很困惑模板。 如果我有一个模板类并将其作为参数传递给函数,请考虑以下内容:

template <class T> class Class
{

};

所以我想创建一个以Class作为参数的函数,那么为什么以下这些还不够:

void func(Class<T> obj)
{

}

我必须这样做:

template <class T> void func(Class<T> obj)
{

}

另外,我说2个模板类的2个参数,请考虑以下内容:

template <class T> class ClassA
{

};
template <class T> class ClassB
{

};

我有一个函数,它接受ClassA和ClassB类型的2个参数,写作之间的区别是什么:

template <class T> void func(ClassA<T> obj1, ClassB<T> obj2)
{

}

template <class T, class ClassB> void func(ClassA<T> obj1, ClassB obj2)
{

}

因为两者都有效。

2 个答案:

答案 0 :(得分:3)

不要对 template-parameter-list class语法中的class ClassB关键字感到困惑。也就是说,class关键字并不表示实际的(甚至没有给定名称的类),而是一个类型的名称,可以推导出来或在 template-argument-list 中指定。或者,(我更喜欢),您可以使用typename关键字,更好地表达其含义:

那是:

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范围内的func名称会影响class ClassB声明。在函数的范围内,这是在 template-argument-list 中推导或指定的类型的名称。也就是说,它几乎可以是任何东西:

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>类型,并且不以任何方式限制推导出第二个参数的类型。

答案 1 :(得分:1)

类模板不是类,函数模板也不是函数,它们只是制作它们的模板。

因此,难怪你不能使用需要相应功能的模板。

模板参数的名称与其范围之外的函数参数的名称具有相同的重要性:
没有任何。在它们的范围内,它们自然会影响外部范围的名称。

因此,令牌T可能不表示您尝试声明(并且另外定义)您的功能的任何内容。
模板中的ClassB作为template-argument-name,表示teplate-argument,而不是某些可能恰好存在的外部范围类。