如何将模板中的非依赖名称的msvc ++代码移植到Linux?

时间:2012-10-30 13:59:16

标签: c++ templates

我可以处理移植平台相关的功能。我有一个问题,我在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上编译?

5 个答案:

答案 0 :(得分:6)

您必须说this->ValueBase<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关键字的第一部分