4

次のクラス階層があるとします。

template< class T >
class TestBase {

public:

    virtual T const & do_foo() = 0;

};

template< class T >
class TestDerived : public virtual TestBase< T > {

public:

    virtual int do_bar() {
        return do_foo() + 1;
    }

};

GCCは以下を吐き出します:

error: there are no arguments to ‘do_foo’ that depend on a template parameter, so a declaration of ‘do_foo’ must be available [-fpermissive]
note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)

ここで、これを既知の型からインスタンス化されたTestBaseから派生するように変更すると(たとえばclass TestDerived : public virtual TestBase< int >、このスニペットは正常にコンパイルされるため、問題はコンパイル時に基本クラスの型が不明であることに関係しているようです。ただし、オブジェクトをインスタンス化していないためです。どちらのクラスでも、なぜこれが重要なのかわかりません。

基本的に、に頼らずにエラーを解決するにはどうすればよい-fpermissiveですか?

4

2 に答える 2

8

非依存名(つまり、テンプレートの引数に依存しない名前)は、テンプレートをインスタンス化するときではなく、解析するときに検索されます。do_foo依存する名前を付ける必要があります。これを実現するには、基本的に2つの方法があります。

virtual int do_bar() {
    return this->do_foo() + 1;
}

また

template< class T >
class TestDerived : public virtual TestBase< T > {

public:
    using TestBase<T>::do_foo;

    virtual int do_bar() {
        return do_foo() + 1;
    }

};
于 2013-01-14T13:14:18.100 に答える
0

その美しさで賞を獲得することはありませんが、このコードはコンパイラーが文句を言うことなく期待どおりに機能します。

virtual int do_bar() {
    return ((TestBase<T> *) this)->do_foo() + 1;
}
于 2013-01-14T13:17:58.483 に答える