考虑下面的代码,该代码试图从迭代器范围构造一个映射:
#include <map>
template< typename C >
typename C::const_iterator cbegin( C const & c )
{
return c.begin();
}
template< typename C >
typename C::const_iterator cend( C const & c )
{
return c.end();
}
int main()
{
typedef std::map<const int, int > Map;
Map m1;
Map m2( m1.begin(), m1.end() );
Map m3( m1.begin(), m1.end(), std::less<const int>() );
Map m4( cbegin( m1 ), cend( m1 ), std::less<const int>() );
}
// cl -nologo -EHsc vc6-map.cpp && vc6-map
// g++ -Wall -Wextra -Weffc++ -std=c++11 -o vc6-map vc6-map.cpp && vc6-map
g++ 4.8.1成功地编译了代码,而Visual C++ 6,SP6(VC6)在构造m2,m3和m4时均失败。
VC6出现以下错误:
prompt>cl -nologo -EHsc vc6-map.cpp && vc6-map
vc6-map.cpp
vc6-map.cpp(22) : error C2664: '__thiscall std::map<int const ,int,struct std::less<int const >,class std::allocator<int
> >::std::map<int const ,int,struct std::less<int const >,class std::allocator<int> >(const struct std::less<int const >
&,const class std::allocator<int> &)' : cannot convert parameter 1 from 'class std::_Tree<int const ,struct std::pair<i
nt const ,int>,struct std::map<int const ,int,struct std::less<int const >,class std::allocator<int> >::_Kfn,struct std:
:less<int const >,class std::allocator<int> >::iterator' to 'const struct std::less<int const > &'
Reason: cannot convert from 'class std::_Tree<int const ,struct std::pair<int const ,int>,struct std::map<int co
nst ,int,struct std::less<int const >,class std::allocator<int> >::_Kfn,struct std::less<int const >,class std::allocato
r<int> >::iterator' to 'const struct std::less<int const >'
No constructor could take the source type, or constructor overload resolution was ambiguous
vc6-map.cpp(23) : error C2664: '__thiscall std::map<int const ,int,struct std::less<int const >,class std::allocator<int
> >::std::map<int const ,int,struct std::less<int const >,class std::allocator<int> >(const struct std::pair<int const ,
int> *,const struct std::pair<int const ,int> *,const struct std::less<int const > &,const class std::allocator<int> &)'
: cannot convert parameter 1 from 'class std::_Tree<int const ,struct std::pair<int const ,int>,struct std::map<int con
st ,int,struct std::less<int const >,class std::allocator<int> >::_Kfn,struct std::less<int const >,class std::allocator
<int> >::iterator' to 'const struct std::pair<int const ,int> *'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
vc6-map.cpp(24) : error C2664: '__thiscall std::map<int const ,int,struct std::less<int const >,class std::allocator<int
> >::std::map<int const ,int,struct std::less<int const >,class std::allocator<int> >(const struct std::pair<int const ,
int> *,const struct std::pair<int const ,int> *,const struct std::less<int const > &,const class std::allocator<int> &)'
: cannot convert parameter 1 from 'class std::_Tree<int const ,struct std::pair<int const ,int>,struct std::map<int con
st ,int,struct std::less<int const >,class std::allocator<int> >::_Kfn,struct std::less<int const >,class std::allocator
<int> >::const_iterator' to 'const struct std::pair<int const ,int> *'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
对于m2,VC6似乎无法调用适当的构造函数。通过指定
std::less
比较器对象,可以解决m3和m4的构造问题。构造m3和m4的错误之间的唯一区别是iterator
与const_iterator
。如何欺骗VC6做所需的工作?
编辑2013年10月14日:VC6 map 范围构造函数的定义如下:
typedef const value_type *_It;
map(_It _F, _It _L, const _Pr& _Pred = _Pr(), const _A& _Al = _A()) {...}
这可以澄清错误:VC6版本要求的
std::pair<> const *
与std::map<>::const_iterator
不同。 最佳答案
给定VC6中的非标准std::map范围构造函数,我看不到从范围构造映射的真正解决方案。
下面的函数add_to_map
提供了一种可与VC6和最新编译器一起使用的解决方法。
template< typename M >
void add_to_map( M & m, typename M::const_iterator f, typename M::const_iterator t )
{
for ( ; f != t; ++f )
{
m.insert( *f );
}
}
int main()
{
typedef std::map<const int, int > Map;
Map m1;
Map m5;
add_to_map( m5, m1.begin(), m1.end() );
}
请注意,以下内容在VC6中不起作用(模板参数“U”不明确):
template< typename T, typename U >
void add_to_map( std::map<const T,U> & m, ... )