当我有两个模板化函数重载时,如下所示:
template<class T>
void foo( T const& )
{
// do something with a const reference
cout << "const reference version";
}
template<class T>
void foo( T const* )
{
// do something with a const pointer
cout << "const pointer version";
}
为什么编译器在使用非常量指针类型实例化时会选择第一个版本?
int* bar;
foo( bar ); // prints "const reference version"
char const* baz;
foo( baz ); // prints "const pointer version"
答案 0 :(得分:4)
原因是因为bar
是一个非常量指针,所以int* const&
实际上比int const*
更好,因为它不必添加const
指针类型。
如果bar
符合const
条件,那么它将与T const*
版本完全匹配。
答案 1 :(得分:2)
#include <iostream>
using namespace std;
void foo(int const&) {
cout << "const reference" << endl;
}
void foo(int const*) {
cout << "const pointer" << endl;
}
int main() {
int *hi;
foo (hi); //const pointer
foo((*hi)); //const reference
foo(&(*hi));//const pointer
}
这里的交易是参考和指针是不同的。指针是一种唯一类型,其中作为对值的引用与值本身没有区别,或者更确切地说,是对象的别名。因此,例如,上面代码的这个版本将无法编译。
#include <iostream>
using namespace std;
void foo(int const&) {
cout << "const reference" << endl;
}
void foo(int) {
cout << "hi there" << endl;
}
int main() {
int hi;
foo(hi); //const reference
}
因为foo的声明含糊不清。编译器无法在它们之间做出决定。
答案 2 :(得分:1)
您可以使用typeid
确定模板类型的内容。
#include <iostream>
#include <typeinfo>
using namespace std;
template<class T> void foo( T const& ) {
cout << "const reference version T="<< typeid(T).name()<<endl;
}
template<class T> void foo( T const* ) {
cout << "const pointer version T="<<typeid(T).name()<<endl;
}
int main() {
int* i_ptr=0;
foo(i_ptr);
const int* ci_ptr=0;
foo(ci_ptr);
}
此输出(注意确切输出将取决于您的编译器)
const reference version T=Pi
const pointer version T=i
这表明在第一种情况T = int*
中,完整参数类型为int* const&
,在第二种T=int
中,完整参数类型为int const *
。
答案 3 :(得分:0)
template<class T> void foo( T const* )
需要T
上的const指针。好吧,如果这是你唯一的声明,那么当你试图将非常量指针作为参数传递时,会出现编译错误。
使用template<class T> void foo( T const& )
,T
类型推断为int*
,它是通过引用该函数给出的。