因此,我一直遇到的一個問題模式並沒有很好的解決方案,那就是如何提供基於模板參數派生自哪種類型的模板專業化。 例如,假設我有:模式可以基於繼承來專門化模板嗎?
template<typename T>
struct implementPersist;
template<typename T>
void persist(T& object)
{
implementPersist::doPersist(object);
}
我想是的用戶堅持要能夠提供implementPersist的實現::持續類型是上述後聲明。原則上這很簡單,但在實踐中很麻煩,但用戶需要爲每種類型提供一個implement實用程序。
更清晰,假設我有:
struct Persistent { virtual void myPersist() = 0; };
struct MyClass : public persistent { virtual void MyPersist() { ...implementation...} };
// Persists subclasses of Persistent using myPersist
template<>
struct implementPersist<Persistent>{ void doPersist(Persistent& p) { p->myPersist(); } };
struct X{};
template<>
struct implementPersist<X>{ void doPersist(X& p) { ...implementation...} };
// Persists subclasses of Persistent using boostPersist
struct MyBoostPersistedObject { virtual void boostPersist() = 0 };
struct Z : public MyBoostPersistedObject { virtual void boostPersist() = 0 };
template<>
struct implementPersist<myBoostPersistedObject>{ void boostPersist() { ...implementation... } };
我的本意是,我提供一個模板實施的所有子類堅持,另一個用於myBoostPersistedObject的所有子類和雜項類不有趣的類結構(例如各種POD類型)。 然而,在實踐中,
implementPersist<Persistent>::doPersist
如果::堅持只會被調用(T &)被稱爲T是正是一個持續對象。它回落到T = myClass的(缺失)泛型情況。一般來說,我希望能夠以基於繼承的通用方式專門化模板。由於清楚的編譯器知道如何做到這一點,並且在決定根據參數調用函數時做到這一點,所以它有點令人沮喪。
void persist(Persistent &); void persist(X &); void persist(myBoostPersistedObject &);
但據我所知,模板無法進行類似的匹配。
一個解決辦法是做這樣的事情:
class persist;
template<typename T, bool hasMyPersistMethod=isDerivedFrom(T,persist)::value >
struct implementPersist;
template<typename T, bool true >
struct implementPersist<T,true>
{
template<> struct implementPersist<X>{ void doPersist(T& p) { p->myPersist(); } }
};
(見here爲isDerivedFrom)。
但是,這要求implementsPersist的初始聲明知道提供實現的類的類型。我想要更通用的東西。
我經常爲這種模式找到用途,以避免爲我的系統中的每個類添加明確的特化。
任何想法?
我無法解釋爲什麼你的編譯器不會做你想要的類型推斷。但是,我的經驗與您的經驗是一致的,因爲模板和繼承看起來不是很好。 – 2009-05-06 05:39:28