模版类继承需显示声明子类成员

作者: , 共 1597 字

在 gcc 中,存在继承关系的模版类,子类无法直接访问父类的成员,即使该成员是protectedpublic

1. 一个简单的例子

#include <iostream> 

template <class  T>
class Base {
public:
    T x;
    Base(T _x) : x(_x) {}
};

template <class T>
class Derived : public Base<T> {
public: 
    Derived(T x) : Base<T>(x) {}
    void log() { 
        std::cout << x << std::endl; 
    }
};

int main()
{
    Derived<int> d(2);
    d.log();
}

gcc编译下会报错:

In member function 'void Derived::log()': 16:22: error: 'x' was not declared in this scope

而且这个错误只会在gcc下出现,vc不会出现该问题。因此,编写跨平台的模版库时,应当去gcc下编译。

另外,这个错误只有在DerivedBase都是模版类时才会出现,这两者任何一个不是模版类,都不会出现编译错误。

2. 原因

原因据说是因为stdandard 14.6/8

When looking for the declaration of a name used in a template definition, the usual lookup rules (3.4.1, 3.4.2) are used for nondependent names. The lookup of names dependent on the template parameters is postponed until the actual template argument is known (14.6.2).

stdandard 16.2是这么说的:

In the definition of a class template or a member of a class template, if a base class of the class template depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

也就是说gcc的编译报错行为符合c++标准。

3. 解决方案

3.1. 通过子类引用

void log() {
    std::cout << Base<T>::x << std::endl; 
}

3.2. 通过 this 引用

void log() {
    std::cout << this->x << std::endl;
}

3.3. 通过 using 将变量引入子类

using Base<T>::x;
void log() {
    std::cout << x << std::endl;
}

Q. E. D.

类似文章:
编程 » C++, C++11
花括号初始化是C++11引入的一种初始化方法。
出现的一个场景是将函数指针用 void
编程 » C++, GCC, 编译链接
LD 在链接生成目标文件时,会从左到有扫描输入的依赖库,当依赖库之间也有依赖关系时,必须将「依赖别人的库」放在「被别人依赖的库」的前面。否则会链接失败!失败的症状有:
相似度: 0.074
编程 » C++, 算法
一个短小、高效的 C++函数,用来判断指定日期是星期几:
相似度: 0.062
编程 » C++
C++的浮点数转整数有四种方法,直接类型转换、round、floor、ceil。其效果如下表:
编程 » Excel
在编辑 Excel 文件时经常遇到的一个问题是,我这边用得好好地,换台机器就变了个样,或者根本用不了。下面是我在日常工作中总结的一些避免这些情况的小技巧。
编程 » C++, 内存检查, Linux
获取程序占用的内存量,是一个诡异的需求。但程序写多了,有时候还真需要,尤其是代码运行出现问题的时候。
相似度: 0.051
boost是除std外最常用的 C++库,覆盖很多常用操作。目前最新的版本是1.59.0
编程 » C++
C++的浮点数转整数有四种方法,直接类型转换、round、floor、ceil。其效果如下表:
最近老遇到一个奇怪的问题。在 VS 2013 编译时,爆出很多警告: