dimanche 18 avril 2021

C++ std::function parameters const reference

I want to write a function, which could receive a ostream, a iterable object v, and a function op. The function is supposed to call op on every element in v, and then send the result to ostream. So I write the following code:

template<typename T,
        typename IN = decltype(*std::declval<T>().begin()),
        typename FT = function<ostream&(ostream&, const IN&)>
        >
void func(ostream& ss, const T& v,
              FT op = [](ostream& os, const IN&v)->ostream&{ return os << v; }) {
    for (const auto& i: v) {
        std::invoke(op, ss, i);
    }
}

int main() {
    vector<int> vec = {1, 2, 3, 4};
    func(cout, vec);
    return 0;
}

When I try to compile these code with clang++, I got following errors.

 /mnt/d/codes/stlprinter/stack.cpp:42:9: error: no matching function for call to 'invoke'
        std::invoke(op, ss, i);
        ^~~~~~~~~~~
/mnt/d/codes/stlprinter/stack.cpp:48:5: note: in instantiation of function template specialization 'func<std::vector<int, std::allocator<int>>, int &, std::function<std::basic_ostream<char> &(std::basic_ostream<char> &, int &)>>' requested here
    func(cout, vec);
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/functional:85:5: note: candidate template ignored: substitution failure [with _Callable = std::function<std::basic_ostream<char> &(std::basic_ostream<char> &, int &)> &, _Args = <std::basic_ostream<char> &, const int &>]: no type named 'type' in 'std::invoke_result<std::function<std::basic_ostream<char> &(std::basic_ostream<char> &, int &)> &, std::basic_ostream<char> &, const int &>'
    invoke(_Callable&& __fn, _Args&&... __args)
    ^
1 error generated.

The error message figures that when call invoke, the type of op is _Callable = std::functionstd::basic_ostream<char &(std::basic_ostream &, int &)> &, but the op is defined by FT = function<ostream&(ostream&, const IN&)>, why the 'const' specifier of the second argument is lost?

Aucun commentaire:

Enregistrer un commentaire