3

コード<BSTR,struct>bstrでマップをキーとして使用し、値を構造化します。

これは機能しますか、それとも何かを再定義する必要がありますか?

コンパイルの問題は見られず、要素を追加することもできます。ただし、map.find()動作しません。要素が存在していても、常に戻りますmap.end()(要素が見つかりません)。

次のように一時的な回避策を実行しました-からmap.begin()にループしmap.end()、各要素に対してlstrcmpWを実行します。これはうまくいくようですが、これが効率的すぎるとは思わないでください。

何が間違っている可能性があるかについての提案/ヒントはありますか?BSTR地図の鍵として使っても大丈夫ですか?マップが非ネイティブデータ型の一部をサポートしていないことを知っています-構造体またはクラス...uは<そのための演算子を定義する必要があります。

4

3 に答える 3

4

キータイプとして、BSTRの代わりにATLのCComBSTRを使用します。CComBSTRは、 operator <をオーバーロードして、現在実行しているポインター(アドレス)比較ではなく、実際の文字列比較を実行します。

CComBSTRは、ライフタイム管理も簡素化します。キータイプとしてBSTRを使用する場合は、BSTRがマップの存続期間よりも長持ちすることを確認する必要があります(実際には、マップが破棄される直前に割り当てを解除する必要があります)。CComBSTRはRAIIの原則に従っているため、手動で割り当てを解除する必要はありません。

于 2012-11-29T16:54:16.983 に答える
3

C++のBSTR型はポインタです。マップは、文字列ではなく、ポインタを相互に比較しています。マップで使用するには、おそらくBSTRのラッパーを作成するか、事前に作成されたラッパーを使用する必要があります。

于 2012-11-29T16:46:03.517 に答える
0

map.begin()からmap.end()にループし、各要素に対してlstrcmpWを実行する代わりに、次のようにunary_functionと組み合わせてstd::find_ifを使用できます。

class IsBSTREqual : public unary_function<std::pair<BSTR,int>,bool>
{
private:
    BSTR str;
public:
     IsBSTREqual(BSTR _str)
     {
         str = ::SysAllocString(_str);
     }
     ~IsBSTREqual()
     {
           if(str)
           {
               ::SysFreeString(str);
           }
      }

      bool operator()(const std::pair<BSTR,int> &v)
     {
         if(!lstrcmpW(v.first,str))
         {
             return true;
         }
         return false;
      }
};

BSTR abc = ::SysAllocString(L"String I want to find");
IsBSTREqual _pred(abc);
std::map<BSTR,int>::iterator _it = 
std::find_if(attr_map.begin(),attr_map.end(),_pred);

if(_it != attr_map.end() )
    {
        cout<<"\nFound";
    }
    else
    {
        cout<<"\nNot found";
    }
于 2019-04-05T12:51:13.170 に答える