首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用std::转换算法将hash_map<string,string>转换为hash_map<wstring,wstring>?

如何使用std::转换算法将hash_map<string,string>转换为hash_map<wstring,wstring>?
EN

Stack Overflow用户
提问于 2012-01-26 20:10:37
回答 2查看 810关注 0票数 0

我知道这应该很简单,但我就是无法摆脱编译错误。下面是我的代码:

代码语言:javascript
复制
template<class C>
struct basic_field_type_map : public hash_map<basic_string<C>, basic_string<C>>
{
};

typedef basic_field_type_map<char> field_type_map;
typedef basic_field_type_map<wchar_t> wfield_type_map;

wfield_type_map::value_type to_wfield_type_map_value(field_type_map::const_reference src)
{
  return wfield_type_map::value_type(to_wstring(src.first), to_wstring(src.second));
}

wfield_type_map to_wfield_type_map(const field_type_map& m)
{
  wfield_type_map res;
  transform(m.begin(), m.end(), res.begin(), to_wfield_type_map_value);
  return res;
}

其中,to_wstring具有以下签名:

代码语言:javascript
复制
wstring to_wstring(const string& s)

编译代码时会出现以下错误:

代码语言:javascript
复制
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(260): error C2678: binary '=' : no operator found which takes a left-hand operand of type 'const std::basic_string<_Elem,_Traits,_Ax>' (or there is no acceptable conversion)
1>          with
1>          [
1>              _Elem=wchar_t,
1>              _Traits=std::char_traits<wchar_t>,
1>              _Ax=std::allocator<wchar_t>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(707): could be 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(std::basic_string<_Elem,_Traits,_Ax> &&)'
1>          with
1>          [
1>              _Elem=wchar_t,
1>              _Traits=std::char_traits<wchar_t>,
1>              _Ax=std::allocator<wchar_t>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(761): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const std::basic_string<_Elem,_Traits,_Ax> &)'
1>          with
1>          [
1>              _Elem=wchar_t,
1>              _Traits=std::char_traits<wchar_t>,
1>              _Ax=std::allocator<wchar_t>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(766): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const _Elem *)'
1>          with
1>          [
1>              _Elem=wchar_t,
1>              _Traits=std::char_traits<wchar_t>,
1>              _Ax=std::allocator<wchar_t>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(771): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(_Elem)'
1>          with
1>          [
1>              _Elem=wchar_t,
1>              _Traits=std::char_traits<wchar_t>,
1>              _Ax=std::allocator<wchar_t>
1>          ]
1>          while trying to match the argument list '(const std::basic_string<_Elem,_Traits,_Ax>, const std::basic_string<_Elem,_Traits,_Ax>)'
1>          with
1>          [
1>              _Elem=wchar_t,
1>              _Traits=std::char_traits<wchar_t>,
1>              _Ax=std::allocator<wchar_t>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\utility(259) : while compiling class template member function 'std::pair<_Ty1,_Ty2> &std::pair<_Ty1,_Ty2>::operator =(std::pair<_Ty1,_Ty2> &&)'
1>          with
1>          [
1>              _Ty1=const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,
1>              _Ty2=std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>
1>          ]
1>          z:\dev\internal\vedtool\defs.h(34) : see reference to class template instantiation 'std::pair<_Ty1,_Ty2>' being compiled
1>          with
1>          [
1>              _Ty1=const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>,
1>              _Ty2=std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>
1>          ]
Build has been canceled.

我正在使用VS2010。

我做错了什么?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-26 20:26:19

映射中的键类型是const,您不能将其赋值给它,这就是std::transform所做的;循环看起来像这样:

代码语言:javascript
复制
for(; first != last; ++first, ++dest)
  *dest = func(*first);  // assignment of key-value pair here

注意,还有一个更大的问题:您的res地图甚至没有足够的空间来容纳field_type_map中的所有内容!你在这里调用了未定义的行为,只是写过了结尾处。

最好的办法是使用for_each手动insert每个新的对

代码语言:javascript
复制
std::for_each(m.begin(), m.end(),
    [&](field_type_map::value_type const& p){
      res.insert(to_wfield_type_map_value(p));
    });
票数 2
EN

Stack Overflow用户

发布于 2012-01-26 20:51:20

您不能使用res.begin()作为transform的输出参数,原因有两个:

  • 映射为空,因此begin()不是有效的迭代器,并且无法重新分配
  • 映射元素。

一种可能是将过时的STL hash_map替换为unordered_map;然后您可以使用std::insert_iterator插入值:

代码语言:javascript
复制
transform(m.begin(), m.end(), 
          inserter(res, res.end()), 
          to_wfield_type_map_value);

如果出于某种原因您确实想使用hash_map,那么这是行不通的,因为hash_map没有insert_iterator使用的带有两个参数的insert函数。据我所知,STL没有合适的插入器,但您可以提供自己的插入器:

代码语言:javascript
复制
template <typename Container>
class hash_insert_iterator {
public:
    hash_insert_iterator(Container & c) : container(&c) {}

    hash_insert_iterator & 
    operator=(typename Container::value_type const & value) {
        container->insert(value);
        return *this;
    }
    hash_insert_iterator & operator*() {return *this;}
    hash_insert_iterator & operator++() {return *this;}
    hash_insert_iterator & operator++(int) {return *this;}

private:
    Container * container;
};

template <typename Container>
hash_insert_iterator<Container> hash_inserter(Container & c) {
    return hash_insert_iterator<Container>(c);
}

或者,直接插入可能比使用transform更简单

代码语言:javascript
复制
for (auto const & value : m) {
    res.insert(to_wfield_type_map_value(m));
}

或者一些等效的forfor_each构造,如果你的编译器不支持基于范围的for循环。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9017915

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档