Search code examples
c++compiler-errorsclangclang++std-function

Problem with using std::function in operator=


I implement iterator, and i want to set comparation function to set bounds fo sequens. So in constructor i takes this arguments

iterator(std::pair<T, std::function<T(T&)>> rhs, const std::function<bool(T&, T&)> cmp): 
        base(rhs), cmp(cmp), gen(range<T>::gen_function(rhs)) {}

next... i trying to to use cmp functor in operator== :

bool operator==(const iterator& rhs) const { return cmp(**this, *rhs); }
bool operator!=(const iterator& rhs) const { return !cmp(**this, *rhs); }

compyle by clang++ (v 11.0.0, Ubuntu 18 )

clang++ -std=c++2a -stdlib=libc++ coroutins_iterator.cpp -v

and compiler gives me error:

./coroutins_iterator.h:52:56: error: no matching function for call to object of type 'const std::function<bool (int &, int &)>'
            bool operator!=(const iterator& rhs) const { return !cmp(**this, *rhs); }
                                                                 ^~~
coroutins_iterator.cpp:31:14: note: in instantiation of member function 'range<int>::iterator::operator!=' requested here
    for (auto a : range<int>(2, 10, [](int &a){ return a * 2; })) {
                ^
/usr/include/c++/v1/functional:2342:9: note: candidate function not viable: expects an l-value for 1st argument
_Rp operator()(_ArgTypes...) const;

how to fix that?

or.. can i make that interface in another way ?


Solution

  • T operator*() const { return gen.current_num(); }
    
    const std::function<bool(T&, T&)> cmp
    
    cmp(**this, *rhs);
    

    There's the problem. The error message explains it:

    error: no matching function for call ... candidate function not viable: expects an l-value for 1st argument

    cmp accepts a non-const lvalue reference. The indirection operator returns a prvalue. Non-const lvalue references cannot bind to rvalues.

    You can either:

    • Change the indirection operator to return a non-const lvalue reference (it will have to be a non-const member function). The non-const lvalue reference argument can bind to non-const lvalues.
    • Or change the function wrapper to accept const reference instead. Const lvalue references can bind to prvalues.