0

さまざまな種類のポインターを格納するために ptr_map を使用しています。

boost::ptr_map<string, any> someMap;

テンプレート化されたクラス オブジェクトをいくつか格納します。

someMap.insert("1", new SomeClass<int>());
someMap.insert("2", new SomeClass<float>());

今、マップから値を取得したいと思います。参照付きのサンプルを次に示します。

template<typename T>
T &get(const string &someKey)
{
    try
    {
        return any_cast<EventType&>(mSignalAssociation.at(signalName));
    } catch(bad_any_cast &e)
    {
        // Logging here
    }
}

get< SomeClass<int> >("1"); // This works

しかし、私は参照が好きではありません。たとえば、キャストが悪い場合やオブジェクトが存在しない場合は NULL を返すことができないためです。

このマップからポインターを取得するにはどうすればよいですか?

T *get(const string &someKey)
{
   return any_cast<EventType*>(mSignalAssociation.at(signalName));
}

これはビルドされますが、キャストに失敗します。なぜですか?

4

3 に答える 3

1

これはどう:

T *get(const string &someKey)
{
   return &any_cast<EventType&>(mSignalAssociation.at(signalName));
}

(ただの推測)

于 2010-06-28T12:46:32.413 に答える
1

関数 any_cast

ポインターが渡された場合、成功した場合は値の内容への同様に修飾されたポインターを返します。それ以外の場合は null が返されます。T が ValueType の場合、保持されている値のコピーを返します。それ以外の場合、T が (おそらく const 修飾された) ValueType への参照である場合、保持されている値への参照を返します。

必要なのは、ポインターのセマンティクスです。コメントで指摘されているように、ptr_mapの使用もやめてください。

map<string, any> someMap;
someMap["1"] = SomeClass<int>();
someMap["2"] = SomeClass<float>();

// this will be a valid pointer because someMap["1"] stores 
// an object of SomeClass<int>
SomeClass<int>* valid_ptr = any_cast<SomeClass<int> >(&someMap["1"]);

// this will be null pointer because someMap["2"] doesn't store
// an object of SomeClass<int>
SomeClass<int>* invalid_ptr = any_cast<SomeClass<int> >(&someMap["2"]);

何らかの理由でこれらの SomeClass オブジェクトへのポインターを格納する必要がある場合は、自分でメモリ管理を行い (いずれかに格納されている要素を手動で解放する)、余分なレベルの間接化を使用して、null でキャストの失敗を検出する必要があると思いますポインター。もしそうなら、おそらくboost::shared_ptrのようなものを使う方が良いでしょう。

map<string, any> someMap;
someMap["1"] = new SomeClass<int>();
someMap["2"] = new SomeClass<float>();

// this will be a valid pointer because someMap["1"] stores 
// an object of SomeClass<int>*
SomeClass<int>** valid_ptr = any_cast<SomeClass<int>*>(&someMap["1"]);

// this will be a null pointer because someMap["1"] does
// not store an object of SomeClass<int>*
SomeClass<int>** invalid_ptr = any_cast<SomeClass<int>*>(&someMap["2"]);
于 2010-06-28T13:38:56.253 に答える
0

しかし、参照は好きではありません。たとえば、キャストが悪い場合やオブジェクトが存在しない場合は NULL を返すことができないためです。

ああ...これが、ポインタ、参照、キャスト、およびメモリ管理コンテナを使用してこれらの体操を行っている理由です! :)

に指摘したように; これは不必要な頭痛の種になります。幸いなことに、問題は解決されました - Boost.Optionalを見てください。

于 2010-06-28T23:38:59.020 に答える