带有派生模板类和继承成员变量的语法拼图

时间:2016-03-29 14:32:30

标签: c++ templates inheritance visual-c++ g++

在移植一些Windows遗留代码并尝试使用gcc / clang进行编译时,遇到了以下我不完全理解的问题:

template<typename T> class Base
{
public:
    Base() {}

    T m_var;
};

template<typename T> class Derived : public Base<T>
{
public:
    Derived()
    {
    #if 1
        Base<T>::m_var = 0;   // fix - compiles with gcc/clang now
    #else
        m_var = 0;            // original - compiles only with MSVC++
    #endif
    }
};

gcc / clang的错误是:

  

错误:使用未声明的标识符'm_var'

不幸的是,有数百个地方在派生类方法中引用了非限定成员变量,我真的不想更改所有这些,以便如果我能提供帮助就可以使用Base<T>::进行限定它

任何人都可以解释为什么gcc / clang似乎需要这个而MSVC ++没有,并建议可能的解决方法?

2 个答案:

答案 0 :(得分:5)

由于Base<T>是依赖库,因此无法通过非限定查找访问其成员。如您所述,您可以通过Base<T>::m_var访问它们。另一种选择是this->m_var

我不确定这是一个简洁的解决方法。一种选择是将T& m_var;数据成员添加到Derived并将其初始化为引用Base<T>::m_var。如果您无法使用额外的参考成员,则可以在任何具有不合格T& m_var = this->m_var;访问权限的函数的开头添加m_var

答案 1 :(得分:2)

正如@TartanLlama所说,由于基本类型取决于模板参数,因此无法通过非限定查找获得该成员。除了以Base<T>::m_varthis->m_var访问它之外,还有一种我非常喜欢的解决方法,因为它只需要为您想要访问的每个类成员键入一次:

只需在using Base<T>::m_var;的类定义中添加Derived即可。这样,m_var将通过普通名称查找找到。