2012-11-21 86 views
1

給定一個基類,該基類包含具有所有派生類(如創建它們)的通用邏輯的公共靜態方法。將子類模板的參數化類型傳遞給基類模板(以及子類的類型,以便在基類的靜態方法中訪問其自定義靜態方法)。這些類型的組合是typedefed新的「類型」(這是在基類中完成的,以避免重複某些代碼)。然後他們在派生類的公共部分重新輸入(類似)。我會用這些類型定義爲包含助手類,如下所示:模板類的模板參數中的typedef不可見

#include <iostream> 
#include <vector> 

#include <cmath> 
#include <cstdlib> 

template< class DERIVED > 
class HELPERS; 

template< class V, class DERIVED > 
struct BASE 
{ 

    typedef typename V::value_type F; 

    static 
    F some_common_operation() 
    { 
     return helpers.approximate_x(DERIVED::value()); // some common logic (HELPERS::approximate_x() here) depending on the value of DERIVED::value() 
    } 

    static 
    DERIVED create_biased(F const & x) 
    { 
     return DERIVED(F(0.5) * (x + some_common_operation())); 
    } 

protected : 

    BASE(F const & x_) 
     : x(x_) 
    { ; } 

    F x; 

private : 

    static 
    HELPERS<DERIVED> const helpers; 

}; 

template< class V, class DERIVED > 
HELPERS<DERIVED> const BASE< V, DERIVED >::helpers; 

template< class V > 
class DERIVED 
    : public BASE< V, DERIVED<V> > 
{ 

    typedef BASE< V, DERIVED<V> > B; 
    friend B; 

public : 

    typedef typename B::F F; 

    DERIVED(F const & x_) 
     : B(x_) 
    { ; } 

    F shape(F const & y) const 
    { 
     return y * x; 
    } 

private : 

    static constexpr 
    F value() 
    { 
     return F(2.0L); // custom data 
    } 

    using B::x; 

}; 

// template<class> class DERIVED1;... 

template< class D > 
struct HELPERS // set of helpers, that operates on classes derived from BASE 
{ 

    typedef typename D::F F; // error: no type named <F> in <class DERIVED<std::vector<double> >> 

    F approximate_x(F const & x) const 
    { 
     using std::sqrt; 
     return sqrt(x); 
    } 

}; 

int main() 
{ 
    DERIVED< std::vector<double> > d(2.0L); 
    return EXIT_SUCCESS; 
} 

我試圖讓在助手類中的定義,但我得到一個錯誤(克++ -std = GNU ++ 11 a.cpp)。

a.cpp: In instantiation of «struct HELPERS<DERIVED<std::vector<double> > >»: a.cpp:44:26: required from «struct BASE<std::vector<double>, DERIVED<std::vector<double> > >» a.cpp:47:7: required from «class DERIVED<std::vector<double> >» a.cpp:97:39: required from here a.cpp:85:27: error: no type named «F» in «class DERIVED<std::vector<double> >»

有什麼不對? Typedef及其所有「祖先」都可以在類鏈中訪問(放置在公共部分中)。

回答

1

這是一個雞蛋問題。

這是因爲當你定義BASE時,DERIVED尚未完全定義(因爲編譯器需要先解析基類)。因此,您無法訪問HELPER中的任何類型定義DERIVED。爲了確保您可以檢查以下不工作,以及:

template< class V, class DERIVED > 
struct BASE 
{ 
    typedef typename V::value_type F; 
    typedef typename DERIVED::F G; // <-- error here 
    ... 
} 

什麼,你可以嘗試爲移動使用HELPERDERIVED,或使用V作爲HELPER參數。

+0

最後,我使用'V'作爲'HELPER'的參數,但是很醜,因爲這膨脹了模板參數的數量。我沒有將HELPER作爲參數傳遞,因爲這將不得不爲所有派生類集中。每次。這會炸燬代碼。 – Orient

+0

基地已將「V」作爲參數。不知道爲什麼你需要一個參數,你可以在'HELPER'中替換它,不是嗎? –