简体   繁体   中英

Create a template to iterate map in C++11 like C++17's structured bindings

C++17 brought us a nicer way to iterate through map using the Structured binding , as shown in thisexample .

I am bound to use C++14 but have a lot of repeating code that iterates over maps.

In C++14 it looks like this:

for (auto const& item : myMap)
{
    std::string key = x.first;
    int value = x.second;
    //Code...
}

Is there a way to create either a template / define / using / anything else that will allow me the convenience of iterating in this manner but still compile as a C++14 application?

for( auto const& [key, value] : myMap)
{
    //Code...
} 

You cannot initialize variables inside the range-based loop until C++20, so the best option, that I can see to use such macro:

#define STRUCTURED_BINDING(a, b, map_item) \
         const auto &a = map_item.first; \
         const auto &b = map_item.second;

So then in your code, you can write something like that:

for(const auto& item: a)
{
    STRUCTURED_BINDING(fst, snd, item);
    std::cout << fst << " " << snd << std::endl;
}

You can improve this macro to be used with tuple ( get<0> , get<1> , ...), rewriting macro to use variadic arguments.

Maybe you can hack something here - but you'd better not.

While @Midren's suggestion will indeed work, I want to suggest that you not do this.

It's true that the C++14 loop is more verbose than in C++17. But - it is easy to understand and well-recognized. Introducing a macro, or a custom gadget - may save you a few characters, but will cost you in Readability and Maintainability . If your macro-based approach were to become very popular, then the readability would become a non-issue and the maintainability would be almost trivial (just making sure everyone uses the same gadget and not redefining it, in larger projects). But - that will never happen, since we already have C++17.

Instead, I would tweak the naming and perhaps spacing to improve clarity. For example, suppose it's a map of foo's to bar's:

for (auto const& foo_bar_pair : myMap) {
    const auto& foo = foo_bar_pair.first;
    const auto& bar = foo_bar_pair.second;

    //Code with `foo` and `bar`
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM