2012-01-22 5 views
1

私のクラスでは、charデータ[1000]があります。私は、キータイプの文字列の地図を私が望むあらゆるタイプのデータにマッピングするためのマップを持つことができるようにしたい。boost :: char []を持つ任意のマップ

私のドライバでは、マップから値を取得したいと考えています。基本的に私のマップを使ってクラスのすべてのデータを保持できるので、クラスのヘッダーで定義されたデータに限らず、実行時にデータを追加したり削除することができます。例えば、クラス定義について

public: 
    void populateMap() 
    { 
    classMap["imgData"] = data; 
    }; 
private: 
    map<string,boost::any> classMap; 
    char data[1000]; 

ドライバー:私はこれを行うと

int main(){ 
    myClass test; 
    map<string,boost::any> myMap; 
    test.populateMap()//populates map with the char data 
    myMap = test.getMap(); 
    char myData[1000] = boost::any_cast<char*>(myMap["imgData"]); //runtime error 
} 

が、私はランタイムキャストエラーが発生します。私はchar [definite_size]とchar *の両方に精通していません。誰かが私の問題がどこにあるのか教えてくれますか?私は文字配列をマップに格納する人々の例はあまり見ない。 char [definite_size]をマップに保存する適切な方法は何ですか?キャストの外観はどのようにマップから外に出てくるのですか(boost ::は地図から抜け出すときに適切な型にキャストする必要があります)

+3

この愚かなCの代わりに、どこでも 'std :: array 'を使ってみてください。 –

+0

私はそれをやろうとしましたが、マップに配列を格納するのが非常に遅いです。配列のアドレスをマップに格納しようとしましたが、どうすれば元に戻すことができますか? std :: arrayと同じ働きをするが、std :: arrayはもはや存在しないboost :: arrayを使用していることに注意してください。最終的には、boost :: arrayをchar *に変換する必要があります。 – imjojo42

+1

ポインタを保存したい場合は、 'std :: unique_ptr >(新しいstd :: array )'または 'std :: unique_ptr (new char [1000])'のいずれかを試してください。後者は配列として直接アクセスできます。 –

答えて

1

C++とCでは、配列の型に違いがあります2つは非常に密接に関連しています。例えば、CとC++、

int array[137]; 

の種類にint[137]、ないint*あります。つまり、Cでarrayを使用すると、最初の要素へのポインタに減衰します。しかし、C++では、配列への参照を取得することは可能です。例えば、このコードは完全に合法である:ここ

/* This function takes a reference to an array of 137 elements as a parameter! */ 
void MyFunction(int (&array)[137]) { 
    /* ... */ 
} 

int myArray[137]; 
MyFunction(myArray); 

は、MyFunctionの引数の型はint (&)[137]、137個の整数の配列への参照です。

テンプレートを使用するとこれが表示されます。私たちは、このテンプレート機能がある場合たとえば、:

template <typename T> void MyFunction(T& arg) { 
    /* ... */ 
} 

int myArray[137]; 
MyFunction(myArray); 

を次にMyFunctionへの呼び出しは、そのargに記入します引数はint[137]を入力しているため、int[137]、というよりもint*です。

boost::any型の代入演算子は、その引数の型を調べてこの情報を格納するテンプレートである(IIRC)です。あなたは

boost::any myAny; 
int myArray[137]; 

myAny = myArray; 

を言うならば、結果として、私はポインタ型が減衰しないので、これは、myAny変数ストアにタイプint[137]ではなくint*のオブジェクトを持つことになりますと思い

これを修正するには、新しいstd::arrayタイプを使用して、配列タイプが格納されていることを明示的に示すことを検討する必要があります。そうすれば、ポインタを要求するのではなく、代わりにstd::array<int, 137>のようなものを取り出そうとします。また、char[1000]をストアドタイプとして使用していることがわかっている場合は、ここでboost::anyを使用しないようにプログラムをリエンジニアリングすることができます。typedefを使用して、格納されているデフォルトのタイプ(ここではchar[1000])をエクスポートして、適切なタイプにキャストすることもできます。

希望すると便利です。

+0

'char [1000]'から 'char *'に明示的にキャストして崩壊させるほうが簡単ではないでしょうか?つまり、 'populateMap'では' classMap ["imgData"] =(char *)data' –

+0

@ NicolBolasです。これは良い点です。実際には、なぜそのタイプは自動的にそれをしませんか? – templatetypedef

+0

おそらくブーストのメンテナーは実際にそれをするのに十分気にしないからです。あるいは、多くの人が、このような問題に遭遇した 'boost :: any'を使用していないからです。 –

関連する問題