2016-08-25 6 views
0

C++で任意の種類の数値データ型(char、short、int、long、float、double)を取り込めるstd::vectorを作成しようとしています。 Javaでjava.lang.Numberに相当するC++がありますか?

、私はList<Number> list = ArrayList<Number>();

C++(好ましく< = C++ 03)の等価があるのを作成することができます。そうでない場合、これを達成する最良の方法は何ですか?

PS - 私は実際に各データ型の1つのベクトルを持っている必要はありません:/

+1

タイプ消去はどうですか? –

+1

[C++クラスラッパーの基本型の可能な複製](http://stackoverflow.com/questions/17793298/c-class-wrapper-around-fundamental-types) –

+3

ユニオンはおそらくあなたのためのものです。 –

答えて

1

何をしたいのための簡単な方法は次のとおりです。

enum datatype 
{ 
    dt_none, 
    dt_char, 
    dt_uchar, 
    dt_short, 
    dt_ushort, 
    dt_long, 
    dt_ulong, 
    dt_float, 
    dt_double 
}; 

struct Any 
{ 
     datatype type; // To know what is stored inside union, not mandatory if you know that in another way 
     union 
     { 
      char vchar; 
      unsigned char vuchar; 
      short vshort; 
      unsigned short vushort; 
      long vlong; 
      unsigned long vulong; 
      float vfloat; 
      double vdouble; 
     } data; 
}; 

std::vector<Any> mydata; 

あなたは労働組合の使用を避けることができますが、それより多くのメモリ(各値+実際の大きさのためにポインタを)取ると、それは使用することがより複雑だ:

struct Any 
{ 
    private: 
     void * data; 
     datatype type; 

    public: 
     Any(): 
      data(NULL), 
      type(dt_none) 
     {} 

     ~Any() 
     { 
      deleteData(); 
     } 

     void deleteData() 
     { 
      // Because deleting a void * is UB, we have to check real datatype 
      if (data != NULL) 
      { 
       if (type == dt_char) 
        delete static_cast<char *>(data); 
       if (type == dt_uchar) 
        delete static_cast<unsigned char *>(data); 
       .... 
      } 
     } 

     datatype getType() const 
     { 
      return type; 
     } 

     void setChar(char v) 
     { 
      deleteData(); 
      data = new char(v); 
      type = dt_char; 
     } 


     char toChar() const 
     { 
      return *static_cast<char *>(data); 
     } 

     ..... 

     void setDouble(double v) 
     { 
      deleteData(); 
      data = new double(v); 
     } 

     double toDouble() const 
     { 
      return *static_cast<double*>(data); 
     } 
}; 

可能な最適化、いくつかのバイトを保存するために、小型のタイプのデータを格納するためのポインタを使用している(しかし、それに車を行いますefully!)。しかし、大きなタイプのデータをたくさん格納すると、さらに良いunionが保存されます。また、ポインタのサイズはプラットフォームに依存するため、ポインタに直接格納できるタイプと移植可能なコードを選択することは困難です。また、64ビットのコンピュータでは、ポインタのサイズは8バイトであり、これも普通のサイズであるdoubleです(この場合、ポインタはすべてunionと同じメモリ消費量ですが、本当に複雑で安全ではありません):

struct Any 
{ 
    private: 
     void * data; 
     datatype type; 

    public: 
     Any(): 
      data(NULL), 
      type(dt_none) 
     {} 

     ~Any() 
     { 
      deleteData(); 
     } 

     void deleteData() 
     { 
      // Because deleting a void * is UB, we have to check real datatype 
      if (type != dt_char && type != dt_uchar && data != NULL) 
      { 
       if (type == dt_double) 
        delete static_cast<double *>(data); 
       .... 
      } 
      data = NULL; 
     } 

     datatype getType() const 
     { 
      return type; 
     } 

     void setChar(char v) 
     { 
      data = reinterpret_cast<void *>(v); 
     } 


     char toChar() const 
     { 
      return static_cast<char>(reinterpret_cast<intptr_t>(data)); 
     } 

     ..... 

     void setDouble(double v) 
     { 
      deleteData(); 
      data = new double(v); 
     } 

     double toDouble() const 
     { 
      return *static_cast<double*>(data); 
     } 
}; 

あなたはあなたのケースで唯一の2つのシンプルなソリューション(私見)持っていると言ってすべてのこと:あなたが本当にメモリを節約したい場合は、

  • をあなたがタイプごとにベクトルを使用する必要があります。
  • またはunion

PSを使用します。また、boost::anyのようなサードパーティのライブラリを見てみることができます。

関連する問題