Search code examples
c++stdreference-wrapper

Problems sorting an array of std::reference_wrapper, referencing vectors


I am a bit stuck on this, I'm using a std::array to store reference wrappers to vectors. I was trying to sort these by the vector's size using std::sort but am unable for reasons I am not quite sure of, even after reading the compiler errors. Will I have to use another sort function because it appears that std::sort implementations use operations that are unavailable for use on reference wrappers.

Thank you :)

Compiler explorer version

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    #include <array>
    #include <string>
    #include <sstream>
    #include <utility>
    
    
    void findSum(const std::vector<int>& vec1, const std::vector<int>& vec2, const std::vector<int>& vec3)
    {    
        std::array<std::reference_wrapper<const std::vector<int>>, 3> vecRefs{vec1, vec2, vec3};
        
        std::sort(std::cbegin(vecRefs), std::cend(vecRefs), [](const auto vecA, const auto vecB) -> bool {
                return vecA.get().size() > vecB.get().size(); //descending order
            });
    
        //vecRefs should now be storing reference wrappers to the vectors with sizes in descending order
    
        //print longest vec first, shortest vec last
        for (const auto vec : vecRefs)
        {
            for (const auto val : vec.get())
            {
                std::cout << val << ' ';
            }
            std::cout << '\n';
        }
    
        //TODO: rest of function(the bit before this can be made into a function)
    }


Solution

  • It's because you are using std::cbegin (const begin) and std::cend (const end) in std::sort.
    It means, that you can't change the order of your array!
    Just replace it with std::begin and std::end like this:

    std::sort(std::begin(vecRefs), std::end(vecRefs), [](const auto vecA, const auto vecB) -> bool {
            return vecA.get().size() > vecB.get().size();
            });