2015-10-27 109 views
0

在模板類中專門化某些模板函數時,似乎前向聲明引發了一個問題。我也是爲了專門化這個功能而專門開發這個類,這似乎是導致這個問題的原因。具有前向聲明的完整類模板專業化

編輯:關於處理功能預創建功能,第二個問題:

processor.H

namespace OM{ 

template<typename MatchT> //fwd decl. ERROR 2. see below. 
class Manager; 

template<typename MatchT> 
class Processor 
{ 
    public: 
      Processor(Manager<MatchT>& mgr_):_manager(mgr_) {} 
      template<int P> 
      void process(); 

      void doProcess(); 

    private: 
      Manager<MatchT>& _manager; 
      template<int P, int... Ps> 
      struct table : table<P-1,P-1, Ps... > {}; 

      template<int... Ps> 
      struct table<0, Ps...> 
      { 
       static constexpr void(*tns[])() = {process<Ps>...}; 
      }; 

      static table<5> _table; 
}; 

} 

#include "processor.C" 

processor.C

namespace OM{ 

#include "MyManager.H" (includes MyManager/MyConfig) 
template<typename MatchT> 
template<int P> 
inline void Processor<MatchT>::process() 
{ 
    ... 
    _manager.send(); //this works.. 
} 

template <> template <> 
inline void Processor<MyManager<MyConfig> >::process<1>() 
{ 
    _manager.send(); //ERROR 1 - see below. 
} 

//ERROR here: 
template<typename MatchT> 
void doProcess() 
{ 
    Processor<MatchT>::_table::tns[2](); ERROR 3 below. 
} 

}  

編譯錯誤:

1. error: invalid use of incomplete type 'class Manager <MyManager<MyConfig> >' 

2. error: declaration of 'class Manager<MyManager<MyConfig> >' 
    class Manager; 

3. error: no type name '_table' in "class Processor<MyManager<MyConfig> >' 
    I'm not calling this from a specialized function, so I'm not sure 
    why I'm getting this. 

我可以移動一些東西以確保_manager調用不在專用函數內,但是如果我不需要,我寧願不要。

+0

'namespace OM {.. #include「MyManager.H」'所以當這個頭文件被包含時,最終代碼中將會包含'namespace OM {namespace OM {'' –

+0

'//這工作..'它可能實際上並沒有,它只是沒有被實例化。 – user657267

+0

Maanger在同一翻譯單元的另一個文件中定義。 – ggs

回答

0

我玩過這個,我想現在我得到了一個類似的結果。

問題是模板專門化和前向聲明一起。這應該是eqvivalent:

template<typename T> struct A; 

template<typename T> class B 
{ 
    template<int N> 
    T f(); 
}; 

template<typename T> class B<A<T>> 
{ 
    A<T> *a; 
    template<int N> 
    T f(); 
}; 

template<typename T> struct A{ T i=1; };//works 

template<> 
template<> 
int B<A<int>>::f<1>() 
{ 
    return a->i + 1; 
} 

//template<typename T> struct A { T i = 1; };//error 

int main() 
{ 
    B<A<int>> b; 
} 

爲模板的編制有兩個階段:

首先,它檢查語法和(部分)的依賴。因此,例如如果B<A<T>>中的a不是指針/引用,而是對象本身,則可以編譯,如果B<A<T>>是在定義了A之後構造的。 (爲我工作)

所以第二個是當編譯器插入參數,在這裏,編譯器必須知道所有的對象來生成代碼。

當完全專門化時,如上所述,編譯器被迫知道所有類型。它已經知道,f功能取決於執行A,所以它不能生成代碼。

因此,您必須在函數特化之前定義AManager

+0

我明白了......對於我來說,改變文件以便首先定義A是一項工作。我可能會這樣做,但現在我已經將呼叫轉移到了經理之外的專門功能中。感謝您看這個! – ggs

+0

@ggs我重寫了這個例子,現在這應該適合你。歡迎您:) –

+0

謝謝我看到了..我還有一個關於此的問題,但是最好爲它另外提一個問題..謝謝。 – ggs