关于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是函数或类的编译时工厂。默认情况下,此类工厂的两个输出在运行时不相关,您可以根据需要添加此类关系。

10-02 02:28
查看更多