代码之家  ›  专栏  ›  技术社区  ›  user48956

基于继承专门化模板的模式是否可能?

  •  3
  • user48956  · 技术社区  · 16 年前

    所以,我经常遇到的一个问题模式并没有很好的解决方案,就是如何提供基于模板参数派生类型的模板专门化。

    template<typename T>
    struct implementPersist;
    
    template<typename T>
    void persist( T& object )
    {
       implementPersist::doPersist( object );
    }
    

    我希望persist的用户能够为在上述步骤之后声明的类型提供implementPersist::persist的实现。这在原则上很简单,但在实践中很麻烦,但用户需要为每种类型提供一个实现。

    更清楚地说,假设我有:

    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
    

    A. 持久的

    虚空持续(持续性); 虚空持续(X&;);

    但据我所知,没有类似的匹配可以做的模板。

    一种解决方法是执行以下操作:

    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

    然而,这要求implementPersist的初始声明知道提供实现的类的类型。我想要更普通的。

    我经常使用这种模式,以避免为系统中的每个类添加显式的专门化。

    2 回复  |  直到 8 年前
        1
  •  3
  •   Yuyo    16 年前

    是的,您可以使用enable_if执行此操作。

    #include <iostream>
    #include <boost/type_traits.hpp>
    using namespace std;
    
    
    template <bool Enable, typename T = void>
    struct enable_if
    {
        typedef T type;
    };
    
    template <typename T>
    struct enable_if<false, T>
    {
    };
    
    template <typename T, typename Enable = void>
    struct persist_t {};
    
    struct A
    {
        virtual void foo() const = 0;
    };
    
    template <typename T>
    struct persist_t<T, typename enable_if<boost::is_base_of<A, T>::value>::type>
    {
        static void persist(T const& x)
        {
            x.foo();
        }
    };
    
    
    struct B : A
    {
        virtual void foo() const { cout << "B::foo\n"; }
    };
    
    template <typename T>
    void persist(T & x)
    {
        persist_t<T>::persist(x);
    }
    
    int main()
    {
        B b;
        persist(b);
    }
    

    enable_if ,我只是在这里提供了完整性。Boost还有一个使用它的例子,与我上面的例子非常相似。

    希望有帮助。

        2
  •  0
  •   Nathan Kitchen    16 年前

    MyClass x(...);
    Persistent * p = &x;
    implementPersist<Persistent> ip;
    ip.doPersist(*p);