关于C ++(11)模板类及其在运行时确定类型的实例化,我有一个棘手的问题:
以下情景: 用户使用配置文件(ROS参数)定义模板类的类型。这仅确定模板类的类型,而不是其他逻辑:
班级定义:
template<typename T>
class MyClass {
//[...]
}
示例代码:
/* [Read parameter and write result to bool use_int] */
std::unique_ptr<MyClass> myclassptr {nullptr};
if(use_int) {
myclassptr.reset(MyClass<int>);
} else {
myclassptr.reset(MyClass<double>);
}
myclassptr->foobar();
/* [more code making use of myclassptr] */
所以这段代码(当然)没有编译,因为必须使用模板类型指定unique_ptr模板。但是,问题出现了,使用reset
分配的所有对象的模板类型必须相同。
一个丑陋的解决方案是将代码myclassptr->foobar();
和以下内容复制到if / else的每个分支中,这是我真的不喜欢的。
我希望看到类似的解决方案:
/* [Read parameter and write result to bool use_int] */
MyClass<use_int ? int : double> myclass;
myclass.foobar();
到目前为止我所读到的是这样的事情也是不可能的。
有人为此提供了一个很好的解决方案吗?
答案 0 :(得分:3)
最简单的方法是:
class IClass{
virtual ~IClass {}
virtual void foobar()=0;
};
template<typename T>
class MyClass:public IClass {
public:
void foobar() override {
// code here
}
};
std::unique_ptr<IClass> myclassptr {};
if(use_int) {
myclassptr.reset(new MyClass<int>());
} else {
myclassptr.reset(new MyClass<double>());
}
myclassptr->foobar();
boost::variant
将是另一种解决方案,但通常用于不相关的类型。可以完成类型擦除,但是当您有不相关的类型时,通常会再次执行类型擦除。
在其他语言中,泛型看起来有点像template
,但它实际上是一个抽象的接口,带有自动生成的类型转换和一些类型检查。 C ++ template
是函数或类编译时工厂。默认情况下,这些工厂的两个输出在运行时是不相关的,如果需要,可以添加这样的关系。
答案 1 :(得分:1)
根据您的需要,您可以使MyClass成为包含int或double的变体类型,或者您可以使用类型擦除来隐藏接口背后的实现。 Boost.Variant库可以帮助实现前者。