【问题标题】:How to construct a std::map from a range in VC6如何从 VC6 中的范围构造 std::map
【发布时间】:2013-10-13 09:27:24
【问题描述】:

考虑下面的代码,它试图从一个迭代器范围构造一个映射:

#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 的错误之间的唯一区别是 iteratorconst_iterator

如何欺骗 VC6 执行所需的操作?

2013 年 10 月 14 日编辑:VC6 地图范围构造函数定义如下:

typedef const value_type *_It;
map(_It _F, _It _L, const _Pr& _Pred = _Pr(), const _A& _Al = _A()) {...}

这澄清了错误:VC6 版本需要 std::pair&lt;&gt; const *std::map&lt;&gt;::const_iterator 不同。

【问题讨论】:

  • VC6 非常糟糕,尤其是在涉及 STL 时。试图伪造它真的没有意义。在未能实现一半 C++98 的编译器上尝试 C++11 构造(例如 cbegin())是徒劳的。花时间升级到 VS2012。请注意,VC6 甚至不针对 Vista,而 XP 已停产。
  • @MSalters 是的,我很清楚这一点,我将尝试迁移“我们的”VC6 项目。问题是它是否可以在合理的时间内完成,我们必须拭目以待。解决 VC6 的怪癖开始看起来像是一种爱好 ;) 顺便说一句,您可能会惊讶于 VC6 在实现当代Catch 测试框架方面取得了长足的进步。

标签: c++ stl visual-c++-6


【解决方案1】:

鉴于 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, ... )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 2011-10-21
    相关资源
    最近更新 更多