2017-01-12 9 views
0

私はvoid*を返す関数を持っています。現在、この関数が完了すると、配列UINT16*がvoid *として返されます。配列の先頭にはUINT16という配列が作成されていますが、今は配列の型を決定してその型を作成する方法が必要です。たとえば、いくつかのデータ処理が行われ、型intの配列を作成する必要があると判断され、int配列が作成されて返されます。 doubleやbyteなどの他の型も作成できます。複数の型にできるC++配列を作成する

これを達成するにはどうすればよいですか?

私の現在のコードは

UINT16* data_out = new UINT16[arraySize]; 

を持っている私は、私は大の場合/他またはスイッチ文を作成することができます知っているが、より良い方法がある場合、私は思ったんだけど。

+3

[boost :: variant](http://www.boost.org/doc/libs/1_63_0/doc/html/variant.html)かもしれません。 –

+0

あなたの問題が 'if/elseのみである場合にスイッチを使用してください。 – Raindrop7

+0

テンプレート特化 – nikau6

答えて

0

えええええええええええええええええええええええええご質問です。私はrnにコメントすることはできません。

コアソリューションが必要な場合は、異なるタイプのアウトレットを持つリンクリストクラスを作成できます。基本的には、だけではなくUINT_64* next;を有するので、あなたが持っているでしょう:

int* nextInt; 
double* nextDouble; 

などなどなどを。次に、doubleをタグ付けする場合は、nextDoubleコンセントを使用します。行くコンセントを見つけるには、intが何かを指しているかどうかを確認してください。もしそうでなければ、次に進む。私はこれが本当に厄介で嵩張るオプションのように思えるが、仕事をしていると思う。

0

Void *can be fun and do some very interestingもの...(私の以前の回答をリンクするため申し訳ありませんが、それは私に来た最初の例です。)機能しかし、彼らは安全ではない、とゼロ型チェックを持っている...

あなたの場合、単純なテンプレート関数とautoキーワードが必要です。私はいくつかの楽しみを持っていた、とvoid *関数を作成しました(それは未定義の動作と思われるものを誘発する)

#include <iostream> 
#include <iomanip> 

template <typename T> 
T * returnAnArray (int size) { 
    T * data_out = new T[size]; 
    return data_out; 
} 

int main() { 
    int size = 3; 
    auto array = returnAnArray<double>(3); 

    for(int i=0;i<size;++i) 
     array[i] = 0; 

    for(int i=0;i<size;++i){ 
     std::cout << std::setprecision(2); 
     std::cout << array[i] << std::endl; 
    } 

    delete [] array; 

    return 0; 
} 

:ような何か

template <typename T> 
void * returnVoidPointerToArray(int size) { 
    return new T[size]; 
} 

使用する機能、しなければなりません

auto chArray = (char*)returnVoidPointerToArray<char>(size); 

しかし、出力は次のようになります:

それは何かを返す可能性があるためにキャストします
5.00 
5.00 
5.00 
ggg 
ggg 
ggg 
Program ended with exit code: 0 

1つの値はどのように2つの文字の配列が初期化されているように見えますか?

そして、コメント者のように、おそらくユニークなポインタを使用することをお勧めします。 :)

+1

'std :: unique_ptr (size);'を返す方が良い。 – Jarod42

+0

"しかし、同じ関数が文字の2次元配列を初期化したように見えます..." - その結果を 'char *'にキャストしているからでしょうか? – davmac

1

それはおそらく何か?

これはうまくいかないが、アップヴォートのおかげです。実際にはうまくいくかもしれませんが、それを使用できるようにするには、Fooによって返された型を知る必要があります。しかしタイプはFooの中で決定されます、それは深刻な概念の欠点です。あなたはこれを働かせる方法を考え直すべきです。

enum class ArrayType 
    { 
     Int, 
     Double 
    }; 

    template <typename T> 
    T* CreateArray(size_t size) 
    { 
     T* t = new T[size]; 
     return t; 
    } 

    void* Foo(param1, param2, etc..) 
    { 
     size_t size; 
     ArrayType type; 

     .. Do things to determine the type 

     switch(type) 
     { 
      case ArrayType::Int: 
       return CreateArray<int>(size); 

      case ArrayType::Double: 
       return CreateArray<double>(size); 

      default: 
       return 0; 
     } 

     return 0; 
    } 
0

私はあなたがvoid*を使用して、実質的に型指定されていない戻り値を使用する必要がなぜわからないんだけど、のは、そのための理由があると仮定してみましょう。

実際には、アレイを作成して使用するという2つの問題があります。

ロジックに基づいて異なるタイプの配列を作成する場合は、どうにかしてifまたはswitch()を処理する必要があります。希望の結果タイプを決定するロジックを他にどのように表現しますか?しかし、あなたが好きなら、result = malloc(nrOfItems*sizeOfItem)のようなものを使用して、算術計算に基づいて好きなロジックでsizeOfItemを決めることもできます。

もっと面白くて重要なことは、配列の要素にアクセスするには配列の要素の型やサイズに関する知識が必要であるため、呼び出し元がそれぞれの関数の結果を使用する方法です。

と仮定、例えば、次のコード:

void* getSomeItems() { 
    if (std::rand() > 100000) 
    return new char[200]; 
    else 
    return new double[200]; 
} 

int main() { 
    void* someItems = getSomeItems(); 
    double c = ((double*)someItems)[199]; // Critical! 
    // how shall we know if element type is double? 
    // if rand() decided to create items of type char, 
    // this code accesses non allocated memory 
    ... 

だから、あなたの関数は、型が作成され(実際にも、配列の大きさ)、戻り値された情報をお返しすることができない限り、ほとんど不必要です。

これにはvoid*を使用しないことをおすすめします。関数を呼び出す前に型を知っているなら、テンプレート、ベクトルなどを使うことができます。呼び出す前に型やサイズが分からない場合は、割り当てられた配列以外に型/サイズ情報も提供する構造体を返します。

ところで:delete[]/free最後に結果を忘れないでください。

関連する問題