6

これがコンパイルされない理由を誰かが知っていますか? VS 2008 と GCC 4.something の両方を試しましたが、どちらもエラーを吐き出しました。「ThisFunctionDoesNotCompile()」を参照しているかどうかは関係ありません。

'InternalType' を 2 番目のテンプレート パラメーターとして Base に渡すだけでこれを回避できますが、これがエラーとして表示される理由はまだ知りません。

#include <iostream>
using namespace std;

class DataClass
{
public:
    int m_data;
};

template<typename DerivedType>
class Base
{
public:
    int ThisFunctionCompiles()
    {
        // No problems here.

        typename DerivedType::InternalType temp;
        temp.m_data = 5;
        return temp.m_data;
    }

    // error C2039: 'InternalType' : is not a member of 'Derived<InInternalType>'
    typename DerivedType::InternalType ThisFunctionDoesNotCompile()
    {
        return static_cast<DerivedType*>(this)->GetInternalData();
    }
};

template<typename InInternalType>
class Derived : public Base<Derived<InInternalType> >
{
public:
    typedef InInternalType InternalType;

    InternalType GetInternalData()
    {
        return m_internalData;
    }

private:
    InternalType m_internalData;


public:
    void SetInternalData( int newVal )
    {
        m_internalData.m_data = newVal;
    }
};

int main()
{

    Derived<DataClass> testDerived;
    testDerived.SetInternalData( 3 );

    cout << testDerived.GetInternalData().m_data << endl;
    cout << testDerived.ThisFunctionCompiles() << endl;

    // The compiler gives an error regardless of whether or not this is commented out.
    //cout << testDerived.ThisFunctionDoesNotCompile().m_data << endl;

    return 0;
}

これらは、VS 2008 で発生するエラーです。

1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C2039: 'InternalType' : is not a member of 'Derived<InInternalType>'
1>        with
1>        [
1>            InInternalType=DataClass
1>        ]
1>        e:\test\generaltestprogram\generaltestprogram\main.cpp(35) : see reference to class template instantiation 'Base<DerivedType>' being compiled
1>        with
1>        [
1>            DerivedType=Derived<DataClass>
1>        ]
1>        e:\test\generaltestprogram\generaltestprogram\main.cpp(58) : see reference to class template instantiation 'Derived<InInternalType>' being compiled
1>        with
1>        [
1>            InInternalType=DataClass
1>        ]
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C2146: syntax error : missing ';' before identifier 'ThisFunctionDoesNotCompile'
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(27) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(28) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>e:\test\generaltestprogram\generaltestprogram\main.cpp(28) : warning C4183: 'ThisFunctionDoesNotCompile': missing return type; assumed to be a member function returning 'int'

そして、これらはGCCが私に与えるものです:

main.cpp: In instantiation of 'Base<Derived<DataClass> >':
main.cpp:96:   instantiated from 'Derived<DataClass>'
main.cpp:119:   instantiated from here
main.cpp:88: error: no type named 'InternalType' in 'class Derived<DataClass>'
4

1 に答える 1

12

テンプレート化されたクラスBaseがクラスDerivedの親としてインスタンス化される時点では、クラスDerivedは完全な型ではありません。

はのBase<Derived<DataClass> >親クラスであるDerived<DataClass>ため、インスタンス化する前にインスタンス化する必要がDerived<DataClass>あります。したがって、クラスBase<Derived<DataClass> >がテンプレートから構築されるDerived<DataClass>と、前方宣言であるかのように動作します。また、おそらくご存知のとおり、不完全な型のメンバーを参照したり、前方宣言されたネストされた型を参照したりすることはできないため、ここでは運が悪いです。

ちなみに、これが、テンプレートを使用して適切に共変するclone()メソッドを実装することが難しい理由です。ここここ(私の)を参照してください。

于 2009-09-01T22:02:56.843 に答える