带有接口对象的c++模板
C++ templates with interface objects
我有以下无法编译的代码:
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
。我已经更新了我的例子来解释这一点。
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>;
你可以把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
}
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 { };
我认为c++不支持这个。c++模板完全在编译时处理,所以它不支持多态性。这意味着在赋值表达式的两边,模板参数的类型应该完全相同。
我想我明白你的意思了。我不确定这是最好的方法(您可能想看看Boost.Factory)。
template <class T>
class Factory {
public:
virtual T* operator()() = 0;
};
template <class Derived, class Base>
class ConcreteFactory : public Factory<Base> {
public:
virtual Base* operator()() {
return new Derived();
}
};
class Base {
public:
virtual ~Base() {};
};
class Derived1 : public Base { };
class Derived2: public Base {};
class NotDerived {};
int main()
{
Factory<Base>* g;
g = new ConcreteFactory<Derived1, Base>;
g = new ConcreteFactory<Derived2, Base>;
// g = new ConcreteFactory<NotDerived, Base>; // Will not work if you try to do this
}
相关文章:
- .cpp和.h文件中的模板专用化声明
- C++模板来检查友元函数的存在
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 如何在c++中为模板函数实例创建快捷方式
- 使用C++中的模板和运算符重载执行矩阵运算
- 有人能分解一下这个c++模板的语法吗
- 如何在c++17中制作一个模板包装器/装饰器
- 模板化建造师专业化
- 调用专用模板时出错"no matching function for call to [...]"
- 模板元程序查找相似的连续类型名称
- 如何在C++20中创建模板别名的推导指南
- 没有名称的C++模板参数
- 具有重复类型的C++可变模板
- 如何将enable-if与模板参数和参数包一起使用
- 没有用于初始化C++中的变量模板的匹配构造函数