Подтвердить что ты не робот

Замените BOOST_FOREACH на "чистую" альтернативу С++ 11?

Можно ли заменить BOOST_FOREACH в этом примере "чистым" эквивалентом С++ 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;
  }
}

Ключевой особенностью является сохранение пары ключ/значение в ссылках на k и v.

Я пробовал:

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;
}

Но ни одна из идей, основанных на петле, не работала. Предположительно, для цикла, связанного с диапазоном, требуется декларация перед :, поскольку даже:

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!

Есть ли способ выразить одно и то же кратко без повышения в С++ 11?

4b9b3361

Ответ 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

В С++ 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";
  }
}

Это, безусловно, то, что я бы выбрал в новых проектах.