依赖型基类
基类依赖模版参数
template <typename T>
class BBB{
public:
void one(int ){}
};
template <typename T>
class DDD : public BBB<T>
{
public:
void f()
{
one(1); // 依赖型名称实例化时查找
}
};
编译时会有警告:
/home/ubuntu/MyRep/cpp/TestTemplate.cpp:26:4: warning: there are no arguments to ‘one’ that depend on a template parameter, so a declaration of ‘one’ must be available [-fpermissive]
26 | one(1); // 依赖型名称实例化时查找
| ^~~
/home/ubuntu/MyRep/cpp/TestTemplate.cpp: In instantiation of ‘void DDD<T>::f() [with T = int]’:
/home/ubuntu/MyRep/cpp/TestTemplate.cpp:124:6: required from here
/home/ubuntu/MyRep/cpp/TestTemplate.cpp:26:7: warning: ‘one’ was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
26 | one(1); // 依赖型名称实例化时查找
| ~~~^~~
/home/ubuntu/MyRep/cpp/TestTemplate.cpp:26:7: note: declarations in dependent base ‘BBB<int>’ are not found by unqualified lookup
/home/ubuntu/MyRep/cpp/TestTemplate.cpp:26:7: note: use ‘this->one’ instead
one 函数是非依赖名称(可以理解为:没有依赖于模板参数的名称),编译器在看到时就查找,这时 BBB 还没有实例化,先进行普通查找(作用域内),所以找不到 ‘one’ was not declared in this scope
one 同时也是非受限名称 (可以理解为: 前面没有 -> :: . ), 普通查找没找到函数,进行ADL查找。ADL 查找会从关联类和关联名字空间查找
根据第五条,参数类型int ,返回类型 void, 集合也都是空集,仍然找不到 one 函数,所以 and no declarations were found by argument-dependent lookup at the point of instantiation。 ADL : argument-dependent lookup。
代码改为:
this->one(1);
编译通过, 因为将 one 变成了依赖型名称( 根据依赖型名称定义,如果 -> 左边的表达式类型依赖于模板参数,该受限名称(one)也是依赖型名称),而又根据 C++规则,依赖型名称在实例化时才会进行查找,这是BBB已经被实例化,找到了 one。