在C ++中,我有一个参数化为1类的基类,对于每个具有特定附加结构的子类,我想将该子类映射到另一个类型,它也是同一个基类的子类。但是,我的代码生成错误,编译器将不会执行我打算执行的操作。所以
int main()
正常工作?wrap
写入Base<A>* wrap(Sub& )
,如果参数有方法Wrap<A, Sub>
,则返回Sub::g(A& )
,如果不是,则返回Sub
(同一性)?
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;
}
答案 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);
...
}