3

我在代码<BSTR,struct>bstr 中使用映射作为键并构造值。

这会起作用还是我必须重新定义一些东西?

我没有看到编译问题,我也可以添加元素。但是,map.find()不起作用。即使元素存在,它也总是返回map.end()(未找到元素)。

我做了一个临时的解决方法如下 - 通过从map.begin()to循环map.end()并为每个元素执行 lstrcmpW 。这似乎有效,但不要认为这太有效了。

关于可能出错的任何建议/提示?可以BSTR用作地图的键吗?我知道地图不支持某些非本机数据类型 - 结构或类......你需要为此定义一个<运算符。

4

3 回答 3

4

使用 ATL 的CComBSTR作为密钥类型而不是 BSTR。CComBSTR 重载operator<以进行实际的字符串比较,而不是像您当前所做的那样进行指针(地址)比较。

CComBSTR 还简化了生命周期管理。使用 BSTR 作为键类型,您必须确保 BSTR 的寿命超过映射的生命周期(实际上它们必须在映射被破坏之前被释放)。CComBSTR 遵循 RAII 原则,因此您不必进行任何手动释放。

于 2012-11-29T16:54:16.983 回答
3

C++ 中的 BSTR 类型是一个指针。Map 是比较指针而不是字符串。要在地图中使用,您可能应该为 BSTR 编写包装器或使用预制包装器。

于 2012-11-29T16:46:03.517 回答
0

您可以将 std::find_if 与 unary_function 结合使用,而不是从 map.begin() 循环到 map.end() 并为每个元素执行 lstrcmpW,如下所示:

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 回答