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これは、2番目のクラスで非依存名()が使用されているためだと思います。詳細情報

問題は、私が非常に大きなコードベースを持っていることです。このタイプのコードは非常に頻繁に使用されます。規格を見ると間違っていると思います。ただし、を書く必要がない、this->またはBase<T>::を使用するたびに前に置くと非常に便利ですValueusing Base<T>::Value;基本クラスの最大20のメンバーを使用する場合、派生クラスの先頭に書き込むことでさえ問題があります。

だから私の質問は:この種のコードを許可するLinux用のコンパイラはありますか(追加のコンパイラスイッチの有無にかかわらず)?または、このコードをLinuxでコンパイルできるようにする小さな変更はありますか?

4

5 に答える 5

6

は依存する名前なので、this->Valueまたはを言う必要があります。または、派生クラス定義に追加します。これを回避する方法はありません。Base<T>::ValueValueusing 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

Clangは、MSVCのいくつかの互換性フラグをサポートしています。

私は特にそれ-fdelayed-template-parsingがあなたが探しているものだと信じています。

于 2012-10-30T14:32:27.647 に答える
1

あなたの質問に答えるために、はい、このコードを受け入れるLinux用のコンパイラがあります:IntelC++。バージョン13.0.0.079でテスト済み。-fpermissiveコンパイラフラグを使用する必要があります。

私はKerrekSBに同意します。コードを修正するのが最善です。IntelC++が現在の動作を維持するという保証はありません。Microsoftのコンパイラがそれを保持するという保証さえありません。

于 2012-10-30T14:12:27.947 に答える
0

DerivedでValueを使用する場合。次のように再定義できるので、これを避けてください->またはBase ::

using Base<T>::Value

Derivedの定義の中に一度だけ入ると、どこでも使用できるはずです

編集1:申し訳ありませんが、クラスとタイプ名のキーワードに関する最初の部分を削除しました

于 2012-10-30T14:06:01.693 に答える