【问题标题】:Replace BOOST_FOREACH with "pure" C++11 alternative?将 BOOST_FOREACH 替换为“纯”C++11 替代品?
【发布时间】:2012-05-09 20:30:09
【问题描述】:

是否可以将此示例中的BOOST_FOREACH 替换为“纯”C++11 等效项?

#include <map>
#include <functional>
#include <boost/foreach.hpp>
#include <iostream>

int main() {
  std::map<int, std::string> map = {std::make_pair(1,"one"), std::make_pair(2,"two")};
  int k;
  std::string v;
  BOOST_FOREACH(std::tie(k, v), map) {
    std::cout << "k=" << k << " - " << v << std::endl;
  }
}

关键特性是将键/值对保留在对kv 的引用中。

我试过了:

for(std::tie(k,v) : map)
{
  std::cout << "k=" << k << " - " << v << std::endl;
}

auto i = std::tie(k,v);
for(i : map)
{
  std::cout << "k=" << k << " - " << v << std::endl;
}

但基于范围的 for 循环想法似乎都不起作用。大概基于范围的for循环需要在:之前有一个声明,因为即使:

std::vector<int> test;
int i;
for (i : test);

无效。

我能找到的最接近的等价物是:

for (auto it = map.begin(); it!=map.end() && (std::tie(k,v)=*it,1); ++it)
{
  std::cout << "k=" << k << " - " << v << std::endl;
}

它不像BOOST_FOREACH 版本那么简洁!

有没有办法在 C++11 中简洁地表达同样的事情而无需提升?

【问题讨论】:

  • 在第一个示例中,您不是在每次迭代时都复制一个字符串吗?你真的想要吗?

标签: c++ boost c++11 boost-foreach


【解决方案1】:
for (auto & i : map)
{
    std::tie(k,v) = i;
    // your code here
}

【讨论】:

    【解决方案2】:

    这会产生与 Boost 宏相同的输出

    for( auto const& k : map ) {
      std::cout << "k = " << k.first << " - " << k.second << std::endl;
    }
    

    【讨论】:

      【解决方案3】:

      在 C++17 中,这现在可以使用结构化绑定来完成,例如:

      #include <map>
      #include <string>
      #include <iostream>
      
      int main() {
        const std::map<std::string, std::string> map = {std::make_pair("hello", "world")};
        for (auto& [k,v]: map) {
          std::cout << "k=" << k << ", v=" << v << "\n";
        }
      }
      

      这当然是我在新项目中会选择做的事情。

      【讨论】:

        猜你喜欢
        • 2012-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-30
        • 2015-10-18
        • 1970-01-01
        • 2013-04-07
        • 1970-01-01
        相关资源
        最近更新 更多