2015-09-20 32 views
4

所以我們可以說我有很多的模板參數類,其中之一是派生類使用CRTP:如何避免模板參數樣板調用父類的構造時

template <typename Derived, typename A, typename B, typename C, typename D> 
class BaseFoo { 
public: 
    BaseFoo(A& a) {} 
}; 

而且我想繼承它:

class DerivedFoo : public BaseFoo<DerivedFoo, Bc, Cc, Dc, Ec> { 
public: 
    DerivedFoo(A& a) : BaseFoo<DerivedFoo, Bc, Cc, Dc, Ec>(a) {} 
}; 

是否有任何技巧可以避免所有顯式模板參數提及?

如果我仍然需要聲明Derived作爲模板參數,那也行。

+0

你可以使用'typedef'嗎? –

+0

你的意思是類中的typedef?我想是的,但那會寫兩次模板的長列表。 'typedef BaseFoo ParentClass;'你是指DerivedFoo裏面的?由於需要使用CRTP,我不知道如何在課堂外進行typedef。 – alesegdia

+0

不會回答,因爲我猜如果這是有效的,那麼有人會提到它,但是......爲什麼可變參數模板不是這裏的解決方案? –

回答

6

只要使用派生類的名稱並查找其中的基類名稱(如果基類是相關的)。如果它不是依賴的,那麼你可以將基類命名爲非限定的,因爲它在範圍內。不需要所有的模板參數

class DerivedFoo : public BaseFoo<DerivedFoo, Bc, Cc, Dc, Ec> { 
public: 
    DerivedFoo(A& a) : BaseFoo(a) {} 
}; 

每個類都聲明自己的名字。不僅是普通的類,還有類模板實例。所以BaseFoo是指BaseFoo<...>在它自己的範圍和它的派生類的範圍。

+0

哇,不知道這是可能的。我以爲我不得不聲明整個參數列表,因爲'BaseFoo <.......>'就像一個類,而'BaseFoo'不是由它自己定義的。 – alesegdia

+1

@alesegdia:通常和概念上都是真的(天哪很高興遇到懂得這一點的OP),但這是一個例外,以方便。事實上,這是一個教科書中爲什麼允許的例子。 –

+0

太棒了。我似乎在現實生活中通過了一本教科書的例子。謝謝你的訣竅! – alesegdia

5

首先申明DerivedFoo

class DerivedFoo; 

然後typedef

typedef BaseFoo<DerivedFoo, Bc, Cc, Dc, Ec> OtherFoo; 

也可以與using

using OtherFoo = BaseFoo<DerivedFoo, Bc, Cc, Dc, Ec>; 

,或者如果你不關心不得不提Derived

template <typename Derived> 
using OtherFoo = BaseFoo<Derived, Bc, Cc, Dc, Ec>; 

class DerivedFoo : public OtherFoo<DerivedFoo> { 
    .... 
}; 
+0

或更多現代模板別名與使用? – Alex

+0

完美無瑕,工作。正如@Alex所說,使用'using'來獲得現代模板別名是很好的做法。 – alesegdia

+0

一旦我不在電話上,我會編輯 – Alex

相關問題