在移植一些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 ++没有,并建议可能的解决方法?
答案 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_var
或this->m_var
访问它之外,还有一种我非常喜欢的解决方法,因为它只需要为您想要访问的每个类成员键入一次:
只需在using Base<T>::m_var;
的类定义中添加Derived
即可。这样,m_var
将通过普通名称查找找到。