C++ 模板参数匹配、特化
C++ 模板参数匹配、特化
C++ 模板参数匹配、特化
- C++ 模板参数匹配、特化
- 一、模板参数匹配
- 二、特化
- 1.函数模板的重载和特化
- 2.全特化
- 3.偏特化
- 三、主模板、全特化、偏特化的调用顺序
一、模板参数匹配
在定义模板时可以直接调用某个函数,如果在使用时传入的参数类型没有实现该类型函数则会编译报错,必须实现
template<typename T>
void TestFunc(T& t)
{t.Work();
}
两个类型都要传入上面函数,所以必须实现Work方法
class TestClass
{
public:void Work(){printf("Work !!!\r\n");}
};class TestClass1
{
public:void Work(){printf("Work1 !!!\r\n");}
};
这样调用才不会报错
int main()
{TestClass Test;TestClass1 Test1;TestFunc(Test);TestFunc(Test1);system("pause");return 0;
}
二、特化
1.函数模板的重载和特化
当使用模板时,编译器会按照以下顺序寻找匹配的模板:
- 寻找非模板函数(如果有的话,非模板函数在匹配时优先于模板)。
- 寻找最匹配的函数模板或类模板的特化版本。
template<typename T>
void Foo(T t)
{printf("Template\r\n");
}void Foo(const char* str)
{printf("Not Template\r\n");
}int main()
{Foo(1);Foo(2.3f);Foo("hello");system("pause");return 0;
}
2.全特化
正常我们定义一个模板如下:
template <typename T>
class MyClass {
public:void bar() {std::cout << "Primary MyClass" << std::endl;}
};
而一个全特化模板的格式如下
template <>
class MyClass<int> {
public:void bar() {std::cout << "MyClass<int> specialization" << std::endl;}
};
3.偏特化
一个偏特化的定义如下,让参数T的类型是指针类型
template<typename T>
class MyClass<T*>{
public:void bar(){std::cout << "MyClass<T*> partial specialization" << std::endl;}
};
三、主模板、全特化、偏特化的调用顺序
模板匹配的基本概念
- 主模板(Primary Template):定义一个通用的模板。
- 全特化(Full Specialization):为模板的所有参数指定具体的类型或值。
- 偏特化(Partial Specialization):只对模板的部分参数进行特化(只适用于类模板,函数模板不支持偏特化,但可以通过重载实现类似功能)。
注意事项
- 函数模板不能偏特化:但是可以通过重载实现类似的功能。
- 全特化的函数模板:全特化函数模板时,必须已经存在主模板,并且特化版本必须与主模板的某个实例化版本匹配。
- 匹配顺序:编译器在匹配时,总是先匹配非模板函数,然后再匹配模板函数,并且选择最特化的模板(如果匹配度相同,则选择最特化的版本)。
template <typename T>
class MyClass {
public:void bar() {std::cout << "Primary MyClass" << std::endl;}
};// 类模板全特化
template <>
class MyClass<int> {
public:void bar() {std::cout << "MyClass<int> specialization" << std::endl;}
};template<typename T>
class MyClass<T*>{
public:void bar(){std::cout << "MyClass<T*> partial specialization" << std::endl;}
};int main()
{MyClass<double> obj1;obj1.bar();MyClass<int> obj2;obj2.bar();MyClass<char*> obj3;obj3.bar();system("pause");return 0;
}
总结:
当多个模板可能匹配时,编译器按以下优先级选择:
完全特化:最具体匹配
部分特化:更特化匹配
主模板:最通用匹配