Link iteration?

I would like to perform the same operation on multiple arrays, something like:

#include<vector> #include<algorithm> int main(void){ std::vector<double> a, b; for(auto& ab:{a,b}) std::sort(ab.begin(),ab.end()); // error } 

This code does not work since auto& is a constant reference. Is there an elegant way around it?

+6
source share
3 answers

I think the problem is that it is a bit like binding a temporary to a non-constant link. There is no β€œspecific” collection, so it looks a bit like a temporary one.

If you have a temporary vector, it will be bound to a constant reference, but not to a non-constant one.

I also think that this will never work, what you do, but this should work:

 #include<vector> #include<algorithm> int main(void) { std::vector<double> a, b; for(std::vector<double>* ab:{&a,&b}) std::sort(ab->begin(),ab->end()); // or begin(*ab),end(*ab) } 

and cars can work too.

+7
source

This code does not work since auto & is a constant reference. [emphasis mine]

Your reasoning is not fulfilled. In a range-based loop, what you declare (here, auto& ab ) is not related to the range expression (here {a,b } ). Instead, ab will be initialized from the elements of the range, not the range itself.

Instead, an error occurs when calling std::sort with the parameters ab.begin() / ab.end() , which is easy to testify by commenting on the body of the loop. As RMartinho pointed out, the std::initializer_list<std::vector<double>> elements are immutable, and you cannot sort the const container ( std::sort shuffle the elements by moving, cannot assign the const element).

Assuming you want to (independently) sort both vectors, you can do:

 for(auto& ab: { std::ref(a), std::ref(b) }) std::sort(std::begin(ab.get()), std::end(ab.get())); 

Note that in accordance with the rules for outputting template arguments auto& here is good, and auto will be displayed on const std::reference_wrapper<std::vector<double>> , which gives std::reference_wrapper<std::vector<double>> const& as type ab .

+2
source

I think CashCows is a great solution. Just show a different way: you can also use variable templates to solve this problem.

 #include <vector> #include <algorithm> using namespace std; void mysort() {} // termination version template<typename Arg1, typename... Args> void mysort(Arg1 &arg1, Args&... args ) { sort(arg1.begin(), arg1.end()); mysort(args...); } int main(void) { vector<double> a, b; mysort(a, b); } 

@CashCow: you can pass the algorithm as an argument, but it is a little ugly due to the use of decltype:

 #include <vector> #include <algorithm> using namespace std; template<typename Algo> void mysort(Algo algo) {} // termination version template<typename Algo, typename Arg1, typename... Args> void mysort(Algo algo, Arg1 &arg1, Args&... args ) { algo(arg1.begin(), arg1.end()); mysort(algo, args...); } int main(void) { vector<double> a, b; mysort(&sort<decltype(a.begin())>, a, b); } 
0
source

Source: https://habr.com/ru/post/907840/


All Articles