no match for call while std::sort with lambda functin

I'm trying to sort a vector using std::sort, i.e

ScanIndex::ScanIndex(std::vector<ScanData*> *scans, int currVersion, KeyCell minKey, KeyCell maxKey){
        std::sort(scans->begin(), scans->end(),
         [](const ScanData *& a, const ScanData *& b) -> bool
         {
             return (a->version.load() > b->version.load());
         });
}

While having this error:

/usr/include/c++/5/bits/predefined_ops.h: In instantiation of ‘constexpr bool __gnu_cxx::__ops::_Iter_comp_iter<_Compare>::operator()(_Iterator1, _Iterator2) [with _Iterator1 = __gnu_cxx::__normal_iterator<ScanData**, std::vector<ScanData*> >; _Iterator2 = __gnu_cxx::__normal_iterator<ScanData**, std::vector<ScanData*> >; _Compare = ScanIndex::ScanIndex(std::vector<ScanData*>*, int, KeyCell, KeyCell)::<lambda(const ScanData*&, const ScanData*&)>]’:
/usr/include/c++/5/bits/stl_algo.h:1842:14:   required from ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<ScanData**, std::vector<ScanData*> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<ScanIndex::ScanIndex(std::vector<ScanData*>*, int, KeyCell, KeyCell)::<lambda(const ScanData*&, const ScanData*&)> >]’
/usr/include/c++/5/bits/stl_algo.h:1880:25:   required from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<ScanData**, std::vector<ScanData*> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<ScanIndex::ScanIndex(std::vector<ScanData*>*, int, KeyCell, KeyCell)::<lambda(const ScanData*&, const ScanData*&)> >]’
/usr/include/c++/5/bits/stl_algo.h:1966:31:   required from ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<ScanData**, std::vector<ScanData*> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<ScanIndex::ScanIndex(std::vector<ScanData*>*, int, KeyCell, KeyCell)::<lambda(const ScanData*&, const ScanData*&)> >]’
/usr/include/c++/5/bits/stl_algo.h:4729:18:   required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<ScanData**, std::vector<ScanData*> >; _Compare = ScanIndex::ScanIndex(std::vector<ScanData*>*, int, KeyCell, KeyCell)::<lambda(const ScanData*&, const ScanData*&)>]’
/home/dvir/CLionProjects/KiWi-cpp-pq-port/ScanIndex.cpp:38:11:   required from here
/usr/include/c++/5/bits/predefined_ops.h:125:46: error: no match for call to ‘(ScanIndex::ScanIndex(std::vector<ScanData*>*, int, KeyCell, KeyCell)::<lambda(const ScanData*&, const ScanData*&)>) (ScanData*&, ScanData*&)’
         { return bool(_M_comp(*__it1, *__it2)); }

This is the ScanData object

class ScanData{
public:
    static const ScanData* empty_ScanData;

    ScanData(KeyCell min, KeyCell max) : min(min), max(max), version(0)
    {}

    ScanData(const ScanData& scanData) : min(scanData.min), max(scanData.max), version(version.load())
    {}

    std::atomic<int> version;
    KeyCell min;
    KeyCell max;

};

I'm guessing that I've declared a different type(signature) of lambda than the one expected, but it seems to correspond to the signature in the docs.
Thoughts?

1 answer

  • answered 2019-02-10 12:41 StoryTeller

    scans is a pointer to a vector containing ScanData*.

    Therefore, the lambda can expect an argument that may bind to ScanData* const &.

    The type you specify is const ScanData* & (the referred to pointer is not const, but the pointee). The qualifications are mismatching. While a conversion is possible from ScanData* to const ScanData*, that will require a temporary pointer, and a non-const lvalue reference cannot bind to one.

    Since pointers are value types, and cheap to copy value types at that, just don't pass by reference. Pass the pointers by value to the lambda.

         [](const ScanData *a, const ScanData *b) -> bool
         {
             return (a->version.load() > b->version.load());
         });