模板使用没有尖括号-重载?



我对使用template<>括号和不使用它们的想法有点困惑。当我编译代码时,我得到了我意想不到的输出,也不知道为什么。

例如,假设我有两个函数和一个具有相同原型的template:
using namespace std;
template<typename T> void copy(T a, T b)
{
cout << "template copy" << endl;
}
void copy(int a, int b)
{
cout << "int copy" << endl;
}
void copy(string a, string b)
{
cout << "string copy" << endl;
}

编译完main函数后:

int main()
{
copy<int>(1, 2);
copy<string>("ha", "ha");
copy("ab", "bc");
copy(1, 2);

return 0;
}

输出如下:

template copy
template copy
template copy
int copy

对于记录,所有的代码都写在同一个CPP文件中。

您必须记住,字面值字符串实际上是(常量)字符数组,它衰变成指向char(即const char*)的(常量)指针。

由于接受std::string参数的函数不是直接匹配,并且编译器不会进行转换,因此将使用模板重载(作为copy<const char*>)。

在这些调用中

copy<int>(1, 2);
copy<string>("ha", "ha");

您显式指定了模板参数。因此编译器将只考虑模板函数。

copy("ab", "bc");

没有指定模板参数。因此,编译器将考虑所有名称为copy的重载函数,并选择最可行的函数。

表示字符串字面值的参数类型为const char [3]

由于标准转换顺序,实参被显式转换为指向const char *类型的字符串字面值的第一个字符的指针。

因此编译器可以推断出模板实参的类型为const char *

调用非模板函数

void copy(string a, string b)
{
cout << "string copy" << endl;
}

编译器需要再使用一次转换(用户定义的转换)来将指针转换为std::string类型的对象。

因此,由于模板函数需要较少的转换,因此编译器认为它更合适。结果得到输出

template copy

这是一个示范程序。

#include <iostream>
#include <iomanip>
#include <type_traits>
template <typename T>
void f( T , T )
{
std::cout << std::boolalpha << std::is_same<T, const char *>::value << 'n';
}
int main() 
{
f( "ab", "bc" );

return 0;
}

程序输出为

true

相关内容

  • 没有找到相关文章