为什么未声明从基本模板 class 继承的成员函数?

Why inherited member function from base template class not declared?

我正在测试以下代码:

#include <iostream>

template<typename T>
class A {
public:
    void koo(T) { std::cout << "Hello world!"; }
};

template <typename T>
class B : public A<T> {
public:
    void pun(T i) { koo(i); }
};

int main() {
    B<int> boo;
    boo.pun(5);
}

编译信息为:

main.cpp:12:24: error: ‘koo’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
   12 |     void pun(T i) { koo(i); }
      |                     ~~~^~~
main.cpp:12:24: note: declarations in dependent base ‘A’ are not found by unqualified lookup
main.cpp:12:24: note: use ‘this->koo’ instead

我知道我可以用 this->koo(i)A<T>::koo(i) 避免这个错误,但我想了解 为什么会出现这个编译错误.

我认为 pun 定义中的 koo 是一个从属名称,根据 dependent name / lookup rules “模板中使用的从属名称的查找被推迟,直到模板参数已知”。在main函数中,B<int> boo;设置模板参数为int。那么为什么 ADL 不适用于函数表达式 koo(i) ? ————————————————————————————————

让我们暂时搁置 ADL。如果我将 void pun(T i) { koo(i); } 更改为 void pun(T i) { goo(i); },现在新的编译信息是:

main.cpp:12:24: error: ‘goo’ was not declared in this scope; did you mean ‘koo’?
   12 |     void pun(T i) { goo(i); }
      |                     ~~~^~~
      |                     koo

为什么两种情况的编译信息不同?新错误根本没有提到“参数相关查找”。

ADL 是参数依赖查找。在其参数的关联名称空间中查找函数名称。 int 没有关联的名称空间,因此不会发生 ADL。就算出现了,也只会找空闲函数,所以你的方法是找不到的。