使用模板类型参数列表重载模板函数
template function overloading with template type-parameter-list
请帮助理解以下3种不同的语法
#include <iostream>
using namespace std;
template <typename T>
class Demo {
public:
void print_type(){
if(is_same<int,T>())
cout << "Int type" << endl;
if(is_same<float,T>())
cout << "float type" << endl;
}
};
//1. fun
template<typename T>
void fun(Demo<T> a){
cout << "In <T>fun(Demo<T>)" <<endl;
a.print_type();
}
//2. fun
template<typename T=int,class D=Demo<T> >
void fun(D a){
cout << "In <T,class>fun(Demo)" <<endl;
a.print_type();
}
// 3. fun
template<typename T=int,template <typename T> class D=Demo >
void fun(D<T> a){
cout << "In <T,template>fun(Demo<T>)" <<endl;
}
int main()
{
fun(Demo<int>());
fun(Demo<float>());
return 0;
}
-
main
中的函数调用正在调用fun
的第一个版本 - 如果我注释掉
fun
的任何两个定义,第三个定义称为
三种fun
定义的区别是什么?我怎么调用这三个而不注释它们呢?
让我们看一下我们的三个函数:
template <typename T> void fun(Demo<T> ); // (1)
template <typename T, typename D> void fun(D ); // (2)
template <typename T, template <typename> class D> void fun(D<T> ); // (3)
让我们考虑第二个。D
将从第一个参数推导出来,但T
不会出现在任何函数参数中——它是一个非推导的上下文。因此,它必须由调用方显式指定才能被考虑。您没有指定它,因此它是演绎失败,并被抛出重载集。
现在(1)和(3)都是Demo<int>
和Demo<float>
类型参数的可行候选。在这两种情况下,两个函数都接受相同的实参,这些实参对于调用者来说是精确匹配的,并且都是函数模板——因此最后一个决定性因素是考虑哪个函数模板更专门化(这也称为函数模板部分排序)。(1) 只能接受类似Demo<T>
的类型。(3)可以接受Demo<T>
,也可以接受OtherTemplate<T>
或YetAnotherClass<T>
。它更通用——所以我们更喜欢叫它(1)。这个规则很复杂,但如果你感兴趣的话,你可以做更多的搜索。一个更简单的例子可能是:
template <typename T> void foo(T ); // (4)
template <typename T> void foo(T* ); // (5)
foo(new int(42));
两个候选项都是可行的,(4)与T = int*
匹配,(5)与T = int
匹配。但是(4)匹配任何,而(5)只匹配指针,这使得它更专门化,因此是最可行的候选者。
如果你注释掉(2),没有什么变化——它本来就不是一个可行的候选。但是如果你注释掉(1),那么我们调用(3),因为(3)成为唯一可行的候选(因此,平凡地,最好可行的候选)。
相关文章:
- 为什么使用SFINAE而不是函数重载
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- c++:可变模板和函数重载
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 解决模板成员函数重载
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 推断模板化函数中的函数重载
- C++复制函数重载导致"must be a nonstatic member function"错误
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 可变参数泛型 lambda 和函数重载
- C++中的函数重载和继承
- 当有右值构造函数可用时,为什么从右值调用类引用构造函数重载?
- C/C++ 可变参数宏函数重载
- 将基类的成员函数重载到其他派生类C++
- C++ 函数重载匹配
- C++函数重载,具体步骤是什么
- C++:使用 param pack 显式调用函数重载
- 隐式生成的函数重载用于右值参数?
- 使用函数重载输入运算符
- 运算符重载函数上的函数重载