Suppose I have those two std::vector
:
std::vector<int> v_int(1000);
std::vector<T> v_T(1000); // Where T is copy-costy type
if I need to loop through them (sepereatly) without the need for editing the items I may use:
for(const auto item:v_int){
//...
}
for(const auto& item:v_T){ //Note &
//...
}
Iterating using const auto item:v_T
is too bad since a copy will be performed in each iteration. However, using const auto& item:v_int
is not optimal but not that bad. So if I need a code that deal with both them I used to use const auto& item:v
.
Question: Is there a generic way to write the for loop that will use the best declaration for both of them? Something like:
template <typename T>
void iterate(const std::vector<T> v){
for(const auto/*&*/ item:v){ // activate & if T is not elementary type
//...
}
}
Java's Generic has a new loop called for-each loop. It is also called enhanced for loop. This for-each loop makes it easier to iterate over array or generic Collection classes.
Generics in C++ Generics is the idea to allow type (Integer, String, … etc and user-defined types) to be a parameter to methods, classes and interfaces. For example, classes like an array, map, etc, which can be used using generics very efficiently. We can use them for any type.
Loops in Java come into use when we need to repeatedly execute a block of statements. Java for loop provides a concise way of writing the loop structure. The for statement consumes the initialization, condition and increment/decrement in one line thereby providing a shorter, easy to debug structure of looping.
You can do this using the standard type traits:
template <typename T>
using select_type = std::conditional_t<std::is_fundamental<T>::value,
const T, const T&>;
template <typename T>
void iterate(const std::vector<T> v){
for(select_type<T> item:v){ // activate & if T is not elementary type
//...
}
}
However, I question the wisdom of doing this. It just clutters the code for something which is unlikely to make any difference.
Use auto&&
when you just don't care. Use auto const&
when you must guarantee it is not edited.
References are aliases, and in an immediate context like a loop are trivial to optimize out of existence, especially if the value is never modified.
There are some difficulties when a reference is passed over a compilation unit boundary to a function, which is why passing int
by value instead of const&
is advised sometimes, but that does not apply here.
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