我有以下代码不能编译。
class Base {
public:
virtual ~Base() { };
};
class Derived : public Base { };
class NotDerived { };
template <typename T>
class Group { };
int main() {
Group<Base> *g = NULL;
g = new Group<Base>(); // Works
g = new Group<Derived>(); // Error, but I want it to work
g = new Group<NotDerived>(); // Error, as expected
}我知道这是不能编译的,因为g是与Group<Derived>不同的类型。要在Java语言中实现这一点,我需要做一些诸如Group<? extends Base> g之类的操作,但据我所知,C++没有这个关键字。可以做些什么呢?
编辑:我想澄清的是,我不希望将不是从Base派生的类型设置为g。我已经更新了我的示例来解释这一点。
编辑2:我的问题有两种解决方案。我发现Dave's很简单,很容易定义。但是Bowie's (加上Mark's )更适合我的需求。
发布于 2011-08-25 09:55:10
您可以使Base >成为所有Group< T>T != Group<的基类。
class Base {
public:
virtual ~Base() { };
};
class Derived : public Base { };
template <typename T> class Group;
struct Empty { };
template <typename T>
struct base_for_group_t {
typedef Group<Base> type;
};
template <>
struct base_for_group_t<Base> {
typedef Empty type;
};
template <typename T>
class Group : public base_for_group_t<T>::type { };
int main() {
Group<Base> *g = 0;
g = new Group<Base>(); // Works
g = new Group<Derived>(); // now works
}发布于 2011-08-25 09:48:17
类Group<Base>和Group<Derived>是完全不相关的不同类。指向它们的指针在这两个方向上都不能转换。
如果您需要运行时多态行为,您的类模板Group可以从通用(非模板化)基类派生:
class Group // base
{
virtual ~Group() { }
};
template <typename T>
class ConcreteGroup : public Group
{
// ...
T * m_impl;
};
Group * g1 = new ConcreteGroup<A>;
Group * g1 = new ConcreteGroup<B>;发布于 2011-08-25 10:45:39
Bowie Owens's Answer处理解决原始问题所需的协方差。至于你在编辑后的问题中要求的约束--你可以通过使用类型特征来实现。
template <typename T, class Enable = void> class Group;
template <typename T>
class Group<T, typename enable_if<is_base_of<Base, T>::value>::type>
: public base_for_group_t<T>::type { };https://stackoverflow.com/questions/7184183
复制相似问题