2011-10-24 11 views
1
template <class T> 
class Test{ 

public: 
    Test(T){ } 

    template <class U> 
    U to() const{ return U(0); } 
}; 


template <class Real> 
class Base{ 

    typedef Test<Real> TST; 

protected: 
    Base(const TST& t){ 

    _i = t.to<int>(); // <- but this gives error 
    } 

    int _i; 
}; 


template <class Real, class T> class Child; 

template <class Real> 
class Child<Real, int> : public Base<Real>{ 

    typedef Base<Real> F; 
    typedef Test<Real> TST; 

public: 
    Child() : F(TST(23.0)){ } 
}; 



int main(int argc, char* argv[]){ 

    Child<double, int> rw; 

    Test<double> t1(3.3); 
    int i = t1.to<int>(); // <- this works 

    return 0; 
} 

toを主な仕事に呼びますが、Base()で呼び出されたときの理由はわかりません。私が手にエラーがある:tRealはテンプレート引数であるタイプTest<Real>であるので、tの種類は、実際に依存タイプですテンプレートメンバ関数の呼び出しでエラーが発生するのはなぜですか?

t1.cpp: In constructor ‘Base<Real>::Base(const TST&)’: 
t1.cpp:20:15: error: expected primary-expression before ‘int’ 
t1.cpp:20:15: error: expected ‘;’ before ‘int’ 

答えて

4

ので。あなたは使ってコンパイラがtoを知っているようにテンプレート関数をされて必要があります。

_i = t.template to<int>(); 

そうでなければあなたはコンパイラが想定しているものです(多少の誤差を引き起こす)toと呼ばれるtのメンバー、上operator<を使用しようとすることができあなたがそれをマークしない限りtemplatemainから呼び出された場合、タイプt1Test<double>であり、テンプレート引数に依存しないので、コンパイラはそれ自身のテンプレート関数を理解することができます。

+0

ここで、静的メンバーは何ですか? –

+0

OK、静的テンプレートメンバーは、テンプレート構造体またはクラス名の後に 'test'テンプレートを(...)'の後に 'template'キーワードを入れてください。もちろん、過剰リベラルなMSVCからG ++に移植するときには、それについて考え始めるだけです。あなたが夜によく眠れたければ、C++はあなたのためではありません。 –

関連する問題