![](/img/trans.png)
[英]How to use string to string hash_map(hash_map<string, string, stringHashFunction> in Linux C++
[英]How to convert hash_map<string, string> to hash_map<wstring, wstring> using the std::transform algorithm?
我知道这应该很容易,但是我只是无法摆脱编译错误。 这是我的代码:
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
具有以下签名:
wstring to_wstring(const string& s)
编译代码会给我以下错误:
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。
我究竟做错了什么?
谢谢。
映射中的键类型是const
,您不能分配给它,这就是std::transform
所做的; 循环看起来像这样:
for(; first != last; ++first, ++dest)
*dest = func(*first); // assignment of key-value pair here
请注意,还有一个更大的问题: res
映射甚至没有空间来容纳field_type_map
所有内容! 您只是通过写末尾来调用未定义的行为。
最好的选择是使用for_each
手动insert
每个新对:
std::for_each(m.begin(), m.end(),
[&](field_type_map::value_type const& p){
res.insert(to_wfield_type_map_value(p));
});
您不能将res.begin()
用作transform
的输出参数,原因有两个:
begin()
不是有效的迭代器,并且 一种可能性是用unordered_map
替换过时的STL hash_map
; 那么您可以使用std::insert_iterator
插入值:
transform(m.begin(), m.end(),
inserter(res, res.end()),
to_wfield_type_map_value);
如果您确实出于某种原因想要使用hash_map
,则此方法将不起作用,因为hash_map
不具有insert_iterator
使用的两个参数的insert
函数。 据我所知,STL没有合适的插入器,但是您可以提供自己的插入器:
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
更简单:
for (auto const & value : m) {
res.insert(to_wfield_type_map_value(m));
}
或一些等效的for
或for_each
构造,如果您的编译器不支持基于范围的for
循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.