If I have a class object comprised of 3 doubles; x, y and z, is there a way to loop over them in a function?
e.g.
for(i in (x,y,z))
do something;
I can do something similar with explicit casting, but I am wondering if there is a more elegant solution to this.
class testc {
public:
double x, y, z;
testc(double x, double y, double z)
:x(x), y(y), z(z)
{}
};
int main()
{
testc omega(1, 2, 3);
cout << *(double*)&omega << " " << *((double*)&omega +1) << " " << *((double*)&omega +2);
}
In programming, iteration (commonly known as looping) is a process where a step is repeated n number of times until a specific condition is met. Just like every other programming language, Golang has a way of iterating through different data structures and data types like structs, maps, arrays, strings, and so on.
Working of the foreach loop in C++ So basically a for-each loop iterates over the elements of arrays, vectors, or any other data sets. It assigns the value of the current element to the variable iterator declared inside the loop.
Range-based for loop (since C++11) 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.
As of C++20 we may combine structured bindings with range-based for loop initialization statements (the latter is a C++20 feature):
Grammar
for ( init-statement(optional) range-declaration : range-expression ) ...
Specifically, using structured bindings as the init-statement in a range-based for loop:
#include <iostream>
class Foo {
public:
double x, y, z;
Foo(double x, double y, double z) : x(x), y(y), z(z) {}
};
int main() {
const Foo foo(1., 2., 3.);
for (auto [x, y, z] = foo; auto e : {x, y, z}) {
std::cout << e << " ";
} // 1 2 3
return 0;
}
Note, however, that you can only use structured bindings to decompose public members of your class (in your example all members are public). Moreover, for the initializer list in the range-expression of the range based for loop, you may not have conflicting types, meaning this approach is limited to the context of your example: where all public members are of the same type.
Now, if the (public) members of your class as well as the instance of it all have very brief names, we may want to consider omitting the structured bindings and instead list-initialize the class members directly:
const Foo f(1., 2., 3.);
for (auto e : {f.x, f.y, f.z}) {
std::cout << e << " ";
} // 1 2 3
However, albeit arguably briefer, the drawback is that we no longer get any help from the compiler in spotting whether we've actually exactly decomposed all public members (no less, no more) or not, a check that is present when we use structured bindings:
for (auto [x, y] = foo; auto e : {x, y}) { /* ... */ }
// error: type 'Foo' decomposes into 3 elements,
// but only 2 names were provided
for (auto [x, y, z, xx] = foo; auto e : {x, y, z, xx}) { /* ... */ }
// error: type 'Foo' decomposes into 3 elements,
// but 4 names were provided
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With