我有以下代码:
template<class A, class B>
void test(A& a, const B* b)
{ std::cout << "hi" << std::endl; }
template<class A, class B>
void test(A& a, const B** b)
{ std::cout << "hello" << std::endl; }
class TestClass
{};
int main()
{
int a = 5;
TestClass b;
TestClass* c = &b;
test(a, &c);
return 0;
}
不知何故输出是&#34; hi&#34;虽然似乎更好的匹配将是第二个模板功能。当我删除const
作为B*
和B**
的限定词时,我会得到&#34;你好&#34;这对应于第二个模板功能。在这种情况下,编译器如何选择要调用的函数?谢谢!
答案 0 :(得分:3)
鉴于没有从T**
到T const**
的转换,第二个根本没有匹配(没有这样的转换,因为它允许非const
访问const
对象)。但是,从T**
到T* const*
的转化。因此,相应的过载是唯一可行的和使用的过载。
答案 1 :(得分:3)
&c
是TestClass**
,可以提升为TestClass* const *
,但不能提升为const TestClass**
。
您可以通过明确使用test<int, TestClass>(a, &c);
强制显示错误,这将显示无法转换。
答案 2 :(得分:1)
其他答案正确地指出,没有从T**
到const T**
的隐式转换,因此其中一个重载根本不可行。我将解释为什么不允许这种转换。它实际上是作为标准中的一个例子编写的。引用第4.4段,
[注意:如果程序可以将指针T **类型指定给指针 类型为const T **(即,如果允许下面的第1行),程序 可能会无意中修改一个const对象(就像它在第2行上所做的那样)。 例如,
int main() {
const char c = ’c’;
char* pc;
const char** pcc = &pc; // #1: not allowed
*pcc = &c;
*pc = ’C’; // #2: modifies a const object
}