C ++虚拟模板方法 [英] C++ Virtual template method

查看:155
本文介绍了C ++虚拟模板方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个抽象类(我知道它不会编译这种方式,但它是为了理解我想做什么):

I have an abstract class (I know that it will not compile this way, but it's for comprehension of what I want to do) :

class AbstractComputation {
    public:
        template <class T> virtual void setData(std::string id, T data);
        template <class T> virtual T getData(std::string id);
};

class Computation : public AbstractComputation {
    public:
        template <class T> void setData(std::string id, T data);
        template <class T> T getData(std::string id, T data);
};

所以当我调用 setData< double>(foodouble 我想要由 foodouble (这里不是主要关注的内部机制)标识的double设置为double数据。

So when I call setData<double>("foodouble", data) I want the double identified by foodouble (internal mechanism which is not the main concern here) to be set to the double data.

那么如何做呢?

我认为可能有一个意思是通过键入类似 virtual void setData< double>(std :: string id,double data) / code>但我不知道该怎么做。

I think that there may be a mean by typing something like virtual void setData<double>(std::string id, double data) but I don't know how to do it.

推荐答案

问题是,时间多态性(模板)与运行时多态性。语言不允许你的例子中的特定结构的原因是,有潜在的无限不同的类型,可以实例化你的模板成员函数,这又意味着编译器必须生成代码来动态分派这些许多类型是不可行的。

The problem is that you cannot mix static time polymorphism (templates) with runtime polymorphism easily. The reason for the language disallowing the particular construct in your example is that there are potentially infinite different types that could be instantiating your template member function, and that in turn means that the compiler would have to generate code to dynamically dispatch those many types, which is infeasible.

在这里可以做不同的事情来绕过这个限制,基本上是拿走静态或动态多态性。从等式中除去动态多态性可以通过提供不是从中导出的类型来存储< key,value> 映射,然后提供解析只有在基本层:

There are different things that can be done here to get around the limitation, basically either take away the static or the dynamic polymorphism. Removing dynamic polymorphism from the equation could be done by providing a type that is not derived from, to store the <key,value> mappings, and then offering the template that resolves that only at the base level:

class AbstractComputation {
public:
   template <typename T>
   void setData( std::string const & id, T value ) {
      m_store.setData( id, value );
   }
   template <typename T>
   T getData( std::string const & id ) const {
      return m_store.getData<T>( id );
   }
protected:
   ValueStore m_store;
};



现在派生类可以访问 ValueStore 基础和没有多态性的需要。 (这也可以通过在 AbstractComputation 中直接实现功能来实现,但是它可能有助于分离问题)

Now deriving classes can access the ValueStore from the base and there is no need for polymorphism. (This can also be done by implementing the functionality directly in AbstractComputation but it probably makes sense to separate concerns)

另一个选项是保持运行时多态性,但删除静态多态性。这可以通过对基类执行类型擦除,然后分派到采用类型擦除参数的适当(非模板)函数来完成。最简单的版本是使用 boost :: any

The other option is to maintain runtime polymorphism, but remove static polymorphism. This can be done by performing type erasure on the base class and then dispatching to the appropriate (non-templated) function that takes the type-erased arguments. The simplest version of this is just using boost::any:

class AbstractComputation {
public:
   template <typename T>
   void setData( std::string const & id, T value ) {
      setDataImpl( id, boost::any( value ) );
   }
   template <typename T>
   T getData( std::string const & id ) const {
      boost::any res = getDataImpl( id );
      return boost::any_cast<T>( res );
   }
protected:
   virtual void setDataImpl( std::string const & id, boost::any const & value ) = 0;
   virtual boost::any getDataImpl( std::string const & id ) const = 0;
};

如何实现类型擦除是有趣的,但是在这里的范围之外,是一个 boost :: any 是一个具体的(非模板)类型,可以通过对参数使用类型擦除来内部存储任何并且同时允许数据的类型安全检索。

How type erasure is implemented under the hood is interesting, but out of the scope here, the important part is that a boost::any is a concrete (non-templated) type that can store any type internally by using type erasure on the arguments, and at the same time allows for type-safe retrieval of the data.

这篇关于C ++虚拟模板方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆