关于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();
到目前为止,我读到的是这样的事情也是不可能的。
有人对此有很好的解决方案吗?
最佳答案
最简单的方法是:
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
是另一种解决方案,但通常用于不相关的类型。可以执行类型擦除,但是通常,当您要使用一个不相关的类型时,通常要执行一个统一的接口(interface)。在其他语言中,泛型看起来有点像
template
,但实际上是一个抽象接口(interface),具有自动生成的类型转换和一些类型检查。 C++ template
是函数或类的编译时工厂。默认情况下,此类工厂的两个输出在运行时不相关,您可以根据需要添加此类关系。