因此,我一直遇到的一个问题模式并没有很好的解决方案,那就是如何提供基于模板参数派生自哪种类型的模板专业化。 例如,假设我有:模式可以基于继承来专门化模板吗?
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