我可以处理移植平台相关的功能。我有一个问题,我在Linux上尝试的编译器(clang和g ++)不接受以下代码,而msvc ++编译器执行:
template <class T>
class Base {
protected:
T Value;
};
template <class T>
class Derived : public Base<T> {
public:
void setValue(const T& inValue){
Value = inValue;
}
};
int main(int argc, char const *argv[])
{
Derived<int> tmp;
tmp.setValue(0);
return 0;
}
g ++错误:
main.cpp: In member function ‘void Derived<T>::setValue(const T&)’:
main.cpp:11:3: error: ‘Value’ was not declared in this scope
我认为这是由于在第二类中使用了非依赖名称(Value
)。 More information
问题是我有一个非常大的代码库,其中经常使用这种类型的代码。我明白看标准时错了。但是,在每次使用this->
之前不必编写Base<T>::
或Value
非常方便。当你使用~20个基类成员时,即使在派生类的开头写using Base<T>::Value;
也是有问题的。
所以我的问题是:是否有适用于Linux的编译器允许这种代码(有或没有额外的编译器开关)?或者是否有小修改允许此代码在Linux上编译?
答案 0 :(得分:6)
您必须说this->Value
或Base<T>::Value
,因为Value
是一个从属名称。或者,将using Base<T>::Value;
添加到派生类定义中。没有办法解决这个问题。
微软的编译器只是不合标准的,不幸的是你编写了供应商的风格,而不是发布的C ++标准,我担心。
答案 1 :(得分:2)
您可以将using语句添加到派生类中。这可能会让你的生活变得复杂:
template <class T>
class Derived : public Base<T> {
using Base<T>::Value;
public:
void setValue(const T& inValue){
Value = inValue;
}
};
答案 2 :(得分:1)
要回答您的问题,是的,有一个Linux编译器接受此代码:英特尔C ++。测试版本13.0.0.079。您需要使用-fpermissive
编译器标志。
我同意Kerrek SB;最好修复代码。无法保证英特尔C ++能够保持当前的行为。甚至不能保证微软的编译器会保留它。
答案 3 :(得分:1)
Clang支持多个compatibility flags for MSVC。
我特别相信-fdelayed-template-parsing
是您正在寻找的那个。
答案 4 :(得分:0)
如果要在Derived中使用Value。你可以像下面那样重新定义它,所以你要避免这种情况 - >或Base ::
using Base<T>::Value
只有一次在Derived的定义中,你应该能够在任何地方使用它
Edit1:好的抱歉,我删除了关于class和typename关键字的第一部分