模板类的C ++ std :: map [英] C++ std::map of template-class values

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

问题描述

我试图声明一个类,具有指向模板的值的私有 std :: map 这样的东西:

 模板< typename T& 
class DataType {
private:
T type;
};
template< typename T>
class Field {
private:
T value;
DataType< T>值;
};
class Row {
private:
std :: map< unsigned long,Field *>柱;
};好吧,我想原则上 Row

类不应该知道我们想要使用哪种类型的 Field (或 Column 它是第1列中的 Field< int> 或第2列中的 Field< double> 确定 Row :: column 声明的正确语法,或者如果 std :: map



我赞赏你的建议,并提前感谢他们。

解决方案

字段单独不是一个类型,而是一个可以生成一系列类型的模板,例如 Field< int> 字段< double> 。所有这些字段是不相关的,使得一个以某种方式从另一个或这样派生。所以你必须在所有这些生成的类型之间建立一些关系。一种方法是使用一个通用的非模板基类:

  class FieldBase {}; 

template< typename T>
class字段:public FieldBase {
private:
T value;
DataType< T>类型;
};
class Row {
private:
std :: map< unsigned long,FieldBase *>柱;
};

并考虑在代码中使用智能指针代替原始指针。无论你指向一个 Field< double> 还是一个 Field< int> / code>不再是已知的,只能通过在模板派生类设置的基础中保留某种类型的标志来检测 - 或者通过使用


$ b询问RTTI $ b

  dynamic_cast< Field< int> *(field)!= 0 

但是这很丑陋。特别是因为你想要的是一个价值语义。也就是说,你可以复制你的行,它会复制它的所有字段。你会想要一个double,当double存储 - 没有首先使用RTTI来破解你的方式到派生类型。



这样做的一种方法是使用区分的联合。这基本上是一些任意类型的并集,另外一个类型标志,它存储什么值当前存储在该字段(例如是否,double,int,...)。例如:

  template< typename T> 
class Field {
private:
T value;
DataType< T>类型;
};
class Row {
private:
std :: map< unsigned long,
boost :: variant< Field< int>,Field< double> > >
column;
};

boost :: variant为您完成所有的工作。你可以使用访问,使它使用正确的重载调用函子。请查看其手册


I'm attempting to declare a Row and a Column class, with the Row having a private std::map with values pointing to a templated Column. Something like this:

template <typename T>
class DataType {
  private:
    T type;
};
template <typename T>
class Field {
  private:
    T value;
    DataType<T> value;
};
class Row {
  private:
    std::map<unsigned long,Field*> column;
}; 

Well, I suppose in principle the Row class shouldn't have to know which kind of Field (or Column) we'd like to use, i.e. whether it's a Field<int> in column 1 or a Field<double> in column 2. But I'm not sure what's the correct syntax for the Row::column declaration, or if the std::map is limited in this sense and I should be using something else.

I appretiate you suggestions and thank you for them in advance.

解决方案

Field alone is not a type, but a template which can generate a family of types, such as Field<int> and Field<double>. All these fields are not related such that the one is somehow derived from the other or such. So you have to establish some relation between all these generated types. One way is to use a common non-template base class:

class FieldBase { };

template <typename T>
class Field : public FieldBase {
  private:
    T value;
    DataType<T> type;
};
class Row {
  private:
    std::map<unsigned long,FieldBase*> column;
};

And consider using smart pointer instead of that raw pointer in the code. Anyway, now the problem is that the type-information is lost - whether you point to a Field<double> or to a Field<int> is not known anymore and can only be detected by keeping some sort of type-flag in the base which is set by the templated derived class - or by asking RTTI using

dynamic_cast<Field<int>*>(field) != 0

But that's ugly. Especially because what you want there is a value semantic. I.e you would want to be able to copy your row, and it would copy all the fields in it. And you would want to get a double when a double is stored - without first using RTTI to hack your way to the derived type.

One way of doing it is to use a discriminated union. That is basically an union for some arbitrary types and in addition a type-flag, which stores what value is currently stored in that field (e.g whether a double, int, ...). For example:

template <typename T>
class Field {
  private:
    T value;
    DataType<T> type;
};
class Row {
  private:
    std::map<unsigned long, 
             boost::variant< Field<int>, Field<double> > > 
      column;
};

boost::variant does all the work for you. You can use visitation to make it call a functor using the right overload. Have a look at its manual

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

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