Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using std::tie as a range for loop target

I want to do something like the following:

//std::vector<std::pair<TypeA, TypeB>> someInitializingFunction(); {   TypeA a;   TypeB b;    for (std::tie(a, b) : someInitializingFunction()) {     // do stuff;   } } 

However, this is not valid code because, as the standard says, a range based for loop is defined as equivalent to:

{   auto && __range = range-init;   for ( auto __begin = begin-expr,       __end = end-expr;       __begin != __end;       ++__begin ) {     for-range-declaration = *__begin;     statement   } } 

Where a for-range-declaration is defined as:

for-range-declaration: attribute-specifier-seq_{opt} decl-specifier-seq declarator

So what's holding me back is that decl-specifier-seq is not marked as optional?

Therefore, it seems that I must fall back on old style for loops for this one a la:

std::vector<std::pair<TypeA, TypeB>> myList = someInitializingFunction();  {   TypeA a;   TypeB b;    for (auto it = myList.begin(); it != myList.end(); ++it) {     std::tie(a, b) = *it;     // do stuff;   } } 

But it seems a bit messy syntactically for what seems to intuitively be a rather common task, unpacking the result of a function call, which is valid in many other contexts.

Is there a proposal to add something this to the language? Is this even reasonable idea? Is there a better way to do this that I'm overlooking? Am I misreading the standard?

Obviously, I could put together my own function to do this, but that's also a bit messy to use as well.

like image 429
OmnipotentEntity Avatar asked Jan 23 '14 05:01

OmnipotentEntity


People also ask

What is range-based for loop in C++?

Range-based for loop in C++ is added since C++ 11. It executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.

Should we embrace range-based for loops?

Range-based for loops win over classic for loops in the area of clarity and expressiveness with no performance cost. (See Matt Godbolt’s talk on how Compiler Explorer was created to address the question of performance for this specific feature .) So they seem like something we should embrace.

Why use for_each instead of for loops?

In that posting, Jonathan reminds us that for_each is useful as a tool for respecting appropriate levels of abstraction. I’m going to go further and argue that for_each should be used instead of range-based for loops in most cases, because it encourages us to create correct abstraction levels.

Will the loop start and end at the right place?

The loop will automatically start and end at the right place. Want to learn from the best curated videos and practice problems, check out the C++ Foundation Course for Basic to Advanced C++ and C++ STL Course for foundation plus STL.


1 Answers

As of 03-21-2017, Structured Bindings are part of C++.

This allows directly doing the following:

//std::vector<std::pair<TypeA, TypeB>> someInitializingFunction(); for (auto [a, b] : someInitializingFunction()) {   // do stuff; } 
like image 63
OmnipotentEntity Avatar answered Sep 22 '22 04:09

OmnipotentEntity