将具有特殊结构的子类映射到同一个基类的另一个子类中

时间:2014-07-09 19:16:21

标签: c++ templates inheritance c++11 types

在C ++中,我有一个参数化为1类的基类,对于每个具有特定附加结构的子类,我想将该子类映射到另一个类型,它也是同一个基类的子类。但是,我的代码生成错误,编译器将不会执行我打算执行的操作。所以

  1. 如何修复代码以使int main()正常工作?
  2. 可以将模板函数wrap写入Base<A>* wrap(Sub& ),如果参数有方法Wrap<A, Sub>,则返回Sub::g(A& ),如果不是,则返回Sub(同一性)?
  3. using uint = unsigned int;
    
    // for each type A, there is a base class Base<A>
    template <typename A>
    class Base
    {
    public:
        virtual void f(A& ) = 0;
    
    };
    
    
    // for each type A, and for each type Sub having methods 
    // Sub::f(A& ) and Sub::g(A& ), there is a special subclass 
    // of Base<A>, with the name Wrap<A, Sub>.
    //
    // NOTE: the type Sub has more structure, it is actually
    //       a subclass of Base<A>.
    template <typename A, typename Sub>
    class Wrap : public Base<A>
    {
    friend Wrap<A, Sub>* wrap(Sub& sub);
    
    public:
        virtual void f(A& a) override 
        {
            // ... do stuff on 'a', using Sub::f() and Sub::g() ...
        }
    
    private:
        Wrap(Sub& s) : sub_( s ) { }
        Sub& sub_;
    
    
    };
    
    
    // for each type A, and for each type Sub having methods
    // Sub::f(A& ) and Sub::g(A& ), map this to Wrap<A, Sub>
    template <typename A, typename Sub>
    Wrap<A, Sub>* wrap(Sub& sub)
    {
        return new Wrap<A, Sub>( sub );
    }
    
    
    
    // a subclass of Base<uint>, with the additional 
    // structure of having a method Subclass::g(uint& )
    class Subclass : public Base<uint>
    {
    public:
        virtual void f(uint& a) override { /*...*/ }
    
        void g(uint& a) { /*...*/ }
    };
    
    
    
    int main()
    {
        Subclass sub;
    
        Base<uint>* w = wrap( sub );
        // ^ no matching function for call to ‘wrap(Subclass&)’
        //   template argument deduction/substitution failed:
        //   couldn't deduce template parameter ‘A’
    
        uint a = 0;
        w->f( a );
    
        // ... delete w ...
        return 0;
    }
    

2 个答案:

答案 0 :(得分:1)

沿着这些方向的东西也许:

template <typename A>
class Base
{
public:
    typedef A MyType;
    virtual void f(A& ) = 0;
};

template <typename Sub>
Wrap<typename Sub::MyType, Sub>* wrap(Sub& sub)
{
    return new Wrap<typename Sub::MyType, Sub>( sub );
}

答案 1 :(得分:1)

两个问题:

1)Base<uint>* w = wrap(sub);类型A无法推断,因此您必须明确提供:

Base<uint>* w = wrap<uint>(sub);

2)您需要将模板函数正确定义为模板化类的朋友:

template <typename A, typename Sub>
class Wrap : public Base<A>
{
template <typename T1, typename T2>
friend Wrap<T1, T2>* wrap(T2& sub);
...
}

Live Demo