4

我可以处理移植平台相关的功能。我有一个问题,我在 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我相信这是由于在第二类中使用了非依赖名称( )。更多信息

问题是我有一个非常大的代码库,其中经常使用这种类型的代码。我知道在查看标准时这是错误的。this->但是,不必Base<T>::在每次使用Value. using Base<T>::Value;当您使用大约 20 个基类成员时,即使在派生类的开头编写也是有问题的。

所以我的问题是:是否有适用于 Linux 的编译器允许这种代码(有或没有额外的编译器开关)?或者是否有一些小的修改可以让这段代码在 Linux 上编译?

4

5 回答 5

6

您必须说this->Valueor Base<T>::Value,因为Value是从属名称。或者,添加using Base<T>::Value;到您的派生类定义中。没有办法解决这个问题。

Microsoft 编译器只是不符合标准,恐怕您的不幸是按照供应商的风格而不是已发布的 C++ 标准进行编码。

于 2012-10-30T14:05:11.607 回答
2

您可以将 using 语句添加到派生类。这可能只会让你的生活复杂化:

template <class T>
class Derived : public Base<T> {
    using Base<T>::Value;
public:
    void setValue(const T& inValue){
        Value = inValue;
    }
};
于 2012-10-30T14:28:25.783 回答
1

要回答您的问题,是的,有一个接受此代码的 Linux 编译器:英特尔 C++。使用版本 13.0.0.079 测试。您需要使用-fpermissive编译器标志。

不过,我同意 Kerrek SB 的观点;最好修复代码。不能保证英特尔 C++ 将保持当前行为。甚至不能保证微软的编译器会保留它。

于 2012-10-30T14:12:27.947 回答
1

Clang 支持MSVC 的多个兼容性标志

我相信这-fdelayed-template-parsing就是你正在寻找的那个。

于 2012-10-30T14:32:27.647 回答
0

如果您想在派生中使用值。你可以像下面这样重新定义它,所以你避免 this-> 或 Base::

using Base<T>::Value

只需在 Derived 的定义中一次,您应该可以在任何地方使用它

Edit1:好的对不起,我删除了关于类和类型名关键字的第一部分

于 2012-10-30T14:06:01.693 回答