模板重载加上指针到指针

template overloading plus pointer to pointer

本文关键字:指针 重载      更新时间:2023-10-16

我有以下代码:

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;
}

不知怎的,输出是"hi",尽管第二个模板函数似乎更匹配。当我删除const作为B*B**的限定符时,我得到了与第二个模板函数相对应的"hello"。在这种情况下,编译器如何选择要调用的函数?谢谢

假设没有从T**T const**的转换,则第二个根本不匹配(没有这样的转换,因为它将允许非const访问const对象(。然而,存在从T**T* const*的转换。因此,相应的过载是唯一可行和使用的过载。

&c是一个TestClass**,可以升级为TestClass* const *,但不能升级为const TestClass**

您可以通过显式使用test<int, TestClass>(a, &c);来强制执行错误,这将向您显示不可能的转换。

其他答案正确地指出,从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
}