简体   繁体   中英

Why can't I get std::function<std::vector<T>::iterator> to bind to lambda returning that type?

I don't understand why this isn't working. I have a function that returns the result of the std::find method. I read that it returns an iterator to object it finds. But when I try passing the lambda that returns that value it gives me a bunch of errors, why?

void f(std::function<std::vector<int>::iterator()>) {}

int main()
{
    std::vector<int> v{0, 1, 2, 3};

    auto p = [=] (int n) {
        return std::find(v.begin(), v.end(), n);
    };

    f(p);
}

I get a lot of incomprehensible errors. I even did a type check here and it returned true:

std::is_same<std::vector<int>::iterator, decltype(std::find(v.begin(), v.end(), N))>::value;
// -> true

So why doesn't this work when I pass a function to f with std::function that returns this type?

Assuming the int parameter missing in your std::function parameter was a copy-paste mistake, apparently v.begin() and v.end() return const_iterator s rather than normal iterators.

This is due to the fact that your lambda was capturing by value, making your std::vector const (and thus its iterators). Capturing everything by reference works , otherwise, your std::function should return a const_iterator :

#include <vector>
#include <functional>
#include <algorithm>

void f(std::function<std::vector<int>::iterator (int)>) {}

int main()
{
    std::vector<int> v{0, 1, 2, 3};

    auto p = [&] (int n) {
        return std::find(v.begin(), v.end(), n);
    };

    f(p);
}

As you are capturing by value, the captured vector (and associated iterators) are const by default. If you want it to be mutable, you need to change the lambda:

auto p = [=] (int n) mutable {
    return std::find(v.begin(), v.end(), n);
};

因为f期望一个不带参数的函数,但是您的lambda具有一个int参数。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM