C++ For range loops with multiple reference values [a, b] [duplicate] - c++

This question already has answers here:
Do structured bindings and forwarding references mix well?
(1 answer)
What are use cases for structured bindings?
(4 answers)
Closed 1 year ago.
I've seen some people talk about the new abstraction of C++17 in for ranged loops, where one can use multiple iterators/values/references:
for(auto&& [output1, output2] : container)
{...}
I've been trying to find an explanation on Google for it, unsuccessfully, since I believe I'm not using the right terminology. In any case I'd be happy if somebody had a link to the cppreference, as well as answer these questions:
1. Are we using "&&" because [output1, output2] as a whole is an rvalue?
2. Let's assume that output1 and output2 are both of type int. What is the type of "auto"? In other words, what kind of (rvalue?) object is [output1, output2], in case I wanted to not use "auto" and declare it specifically? (Maybe a tuple?)
3. What is happening under the hood? Are two iterators being used behind the scenes (see below)? What would be the non C++17 implementation using real iterator objects?
for(Container::iterator it1 =..., Container::iteratorit2 = ...; it1!=..., it2!=...; ++it1, ++it2)
{...}

Related

Testing if an expression compiles [duplicate]

This question already has answers here:
Portable way to check if expression compiles
(2 answers)
How to check at compile time that an expression is illegal?
(2 answers)
Closed 3 days ago.
Following this question where I ask how to test if an expression that tries to use an input iterator for write compiles (disclaimer, it shouldn't!), I would like to know if it's possible to have a generic solution that, given an expression, we are able to check if the expression will compile or not.
Take an easy example, the input iterator in the linked post. If I try to write with an input iterator:
collections::Array arr = collections::Array<int, 5>{1, 2, 3, 4, 5};
auto it_begin = arr.begin();
*it_begin = 7;
that shouldn't compile, because the operator*() returns a const&.
So, what would be the way, of, given an expression, test if it will compiles?
Extra points (well, just take this in consideration if it's possible):
No macros involved
No SFINAE related stuff

Does using reference in ranged for loop count as "reseating reference to a different object"? [duplicate]

This question already has answers here:
Reference referring to multiple objects, how is it possible? [duplicate]
(2 answers)
Why reference const can be re-assigned in for-statement?
(3 answers)
Closed 21 days ago.
for (int& i : array) {
//do something on i
}
Does this count as "reseating reference i to different objects"?
This, appearently, let i refers to array[0] in first iteration, array[1] in second iteration, ..., and so forth.
Edit 1 in response to comment: I know exact what happens in implementation level. I used compiler explorer to see what does this compile to and I know that this looks completely same as other type of iteration (some level of optimization is assumed). This question is more about on the language level, not implementation.

In C++. whats the difference between (*a).b and a->b? [duplicate]

This question already has answers here:
What is the difference between the dot (.) operator and -> in C++? [duplicate]
(14 answers)
Closed 3 years ago.
I am learning C++ in a advanced programming class from my work since I have only worked in Web and .NET languages so far.
In a midway test the instructor has marked all of my uses of (*a).b as wrong and deducted points for it, which could negatively affect my final score and I need a near perfect score to transision in work from web stack to application stack, so could some of you help me resolve this dispute?
If a is a pointer, there's no difference in functionality at all, and in fact one is expressed in terms of the other [expr.ref§2]:
The expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of [expr.ref] will address only the first option (dot).
If a is an instance of a class with overloaded operators * and ->, there could be a difference. But such a discrepancy would be surprising, and I'd consider the class to have a bug because of this.
In the end, it's all about convention and readability then. The -> operator exists as a shorthand for the */. pair, as it is shorter and has better precedence rules (no need for parentheses). Thus, one would indeed use it rather than */..

c++14 - Is there any difference between vec.begin() and begin(vec) [duplicate]

This question already has answers here:
Why use non-member begin and end functions in C++11?
(7 answers)
Closed 4 years ago.
In this question (https://stackoverflow.com/questions/6926433/how-to-shuffle-a-stdvector) user703016 used the following syntax for accessing the iterators of vector cards_:
For C++98 they recommended using: cards_.begin() and cards_.end()
For C++11 they recommended using: std::begin(cards_) and std::end(cards_)
For C++14, which syntax is preferable, and is there any real difference between the two? Prior to today I've only seen the first syntax.
As long as you're dealing with a vector, it makes no difference which you use.
std::begin() and std::end() will, however, work in some situations where .begin() and .end() won't work. The primary one is working with a built-in array. For example, this will work fine:
char foo[] = "17395";
std::sort(std::begin(foo), std::end(foo));
Of course foo.begin() and foo.end() can't possibly work, since a built-in array doesn't have any member functions.

Double increment on an integer variable, does it work as intended? [duplicate]

This question already has answers here:
Multiple preincrement operations on a variable in C++(C ?)
(2 answers)
Closed 6 years ago.
I have some code with lines which increment a counter.
++ count;
Sometimes I have an if condition which means I should increment count by 2.
count += 2;
Does "double increment'ing" work in the same way?
++ ++ count;
It would be helpful to know if both C and C++ compilers interpret this the same way.
As this is clearly syntactically correct, the question that remains is: "Is this UB because of unsequenced writes?"
It is not (in C++11 and later) because
5) The side effect of the built-in pre-increment and pre-decrement operators is sequenced before its value computation (implicit rule due to definition as compound assignment)
(From here)
So the code is fine as of C++11.
However, the sequencing rules were different before that, and pre-C++11, the code actually has UB.
In C, that code does not even compile.
The fact that the behavior is different between C and C++ and even between different C++ standards and that this question arises in the first place is a hint that the simple count += 2; is the safer and more readable version. You should prefer it over the "cute and clever" ++ ++count;.
There are two methods. One that obviously works, one where you have to ask a question on StackOverflow. There are comments saying "in C++ 11 or later"... How sure are you that your C++ code runs with C++ 11 and not something older? Even if you use extensions that were not part of an earlier language, your language could be C++0x with some extensions.
Clearly you shouldn't care whether the second method works or not, but use the one that obviously works.