C++模版依赖型基类中的 this 作用

阅读 61

2022-03-11

依赖型基类

基类依赖模版参数

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。

精彩评论(0)

0 0 举报