【问题标题】:using BOOST_FOREACH with std::map将 BOOST_FOREACH 与 std::map 一起使用
【发布时间】:2010-10-22 04:19:27
【问题描述】:

我想使用 BOOST_FOREACH 遍历 std::map 并编辑值。我不太明白。

typedef std::pair<int, int> IdSizePair_t;
std::map<int,int> mmap;    
mmap[1] = 1;
mmap[2] = 2;
mmap[3] = 3;
BOOST_FOREACH( IdSizePair_t i, mmap )
    i.second++;
// mmap should contain {2,3,4} here

当然,这不会改变任何事情,因为我没有通过引用进行迭代。所以我用这一行代替(根据 Boost 文档中的示例):

BOOST_FOREACH( IdSizePair_t &i, mmap )

我得到编译器错误:

error C2440: 'initializing' : 
cannot convert from 'std::pair<_Ty1,_Ty2>' to 'IdSizePair_t &'
    with
    [
        _Ty1=const int,
        _Ty2=int
    ]

有什么建议吗?

【问题讨论】:

  • 你用的是什么编译器?我在VS2008上试过你的代码,它工作正常。我也测试了 hvint 的 answer 并且它有效。如果这很重要,我正在使用 boost 1.36。
  • 你可能忘记了 & ?没有它,它会复制另一对,然后常量就无关紧要了。

标签: c++ boost foreach maps std


【解决方案1】:

问题在于该对的第一个成员,它应该是 const。试试这个:

typedef std::map<int, int> map_t;
map_t mmap;  
BOOST_FOREACH( map_t::value_type &i, mmap )
    i.second++;

【讨论】:

  • 谢谢,hvint。做到了。另外(在阅读了您的评论后)我意识到解决它的另一种方法是将原始代码的第一行更改为: typedef std::pair IdSizePair_ty; (这允许我通过引用进行迭代)
  • kmote,是的,实际上这就是我在我的回答中提出的(当我看到 hvint one's 时我删除了它)。另外,你知道它为什么会这样吗?如果您需要解释,我会取消删除我的。
  • 回答stackoverflow.com/questions/795443/…“我得到一个编译错误:错误C2065:'i':未声明的标识符”我得到了同样的错误,直到我意识到我没有#include &lt;boost/foreach.hpp&gt;一旦我添加该解决方案完美运行。奇怪的是,您没有收到错误提示 BOOST_FOREACH 未声明。
  • 有趣的是,typedef 是必要的,因为(至少在 g++ 4.8.5 中)忽略它会使预处理器认为三个参数已传递给 BOOST_FOREACH 而不是只有两个(由于std::map 的模板参数中的逗号)。
【解决方案2】:

这是一个旧线程,但有一个更方便的解决方案。

boost 具有对迭代器范围执行转换的“范围适配器”的概念。对于这个确切的用例(迭代映射键或值)有特定的范围适配器:boost::adaptors::map_values 和 boost::adaptors::map_keys。

所以你可以像这样迭代地图值:

BOOST_FOREACH(int& size, mmap | boost::adaptors::map_values)
{ 
    ++size;
}

更多信息here。

【讨论】:

  • 此解决方案需要包含&lt;boost/range/adaptor/map.hpp&gt;。
【解决方案3】:

另一种选择是使用 BOOST_FOREACH_PAIR,请在此处查看我的答案:

BOOST_FOREACH & templates without typedef

【讨论】:

  • 我喜欢 BOOST_FOREACH_PAIR 的外观,但我没有看到任何官方引用它,而且它不在我使用的 1.46 版本中。它曾经被包含在官方版本中吗?
  • 那只是一个自制的宏——它从未在 boost 中实现。在svn.boost.org/trac/boost/ticket/3469 中以 wontfix 结尾(支持基于 C++11 范围的循环)
【解决方案4】:

从 C++11 开始考虑使用 auto 关键字:

std::map<int,int> mmap;    
mmap[1] = 1;
mmap[2] = 2;
mmap[3] = 3;

BOOST_FOREACH(auto& mpair, mmap)
    mpair.second++;

//mmap will contain {2,3,4} here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 2017-01-18
    • 2014-03-01
    • 2010-12-23
    • 2015-06-21
    • 2014-08-29
    • 1970-01-01
    相关资源
    最近更新 更多