I cannot pass lambda as std::function

前端 未结 2 1384
遥遥无期
遥遥无期 2020-12-01 05:04

Let\'s focus on this example:

template
class C{
    public:
    void func(std::vector& vec, std::function

        
相关标签:
2条回答
  • 2020-12-01 05:38

    It's because the argument (std::function) is a reference. It should be:

    void func(std::vector<T>& vec, std::function<T(const std::string&)> f)
                                                                    ^  ^
                                                                       |
                                                                       f not a reference
    

    So that the argument can be converted to the parameter type.

    Also, the type of the function should match. I.e. it should accept a string reference.

    0 讨论(0)
  • 2020-12-01 05:41

    It's because a lambda function is not a std::function<...>. The type of

    auto lambda = [](const std::string& s) { return std::stoi(s); };
    

    is not std::function<int(const std::string&)>, but something unspecified which can be assigned to a std::function. Now, when you call your method, the compiler complains that the types don't match, as conversion would mean to create a temporary which cannot bind to a non-const reference.

    This is also not specific to lambda functions as the error happens when you pass a normal function. This won't work either:

    int f(std::string const&) {return 0;}
    
    int main()
    {
        std::vector<int> vec;
        C<int> c;
        c.func(vec, f);
    }
    

    You can either assign the lambda to a std::function

    std::function<int(const std::string&)> lambda = [](const std::string& s) { return std::stoi(s); };
    

    ,change your member-function to take the function by value or const-reference or make the function parameter a template type. This will be slightly more efficient in case you pass a lambda or normal function pointer, but I personally like the expressive std::function type in the signature.

    template<typename T>
    class C{
        public:
        void func(std::vector<T>& vec, std::function<T( const std::string)> f){
            //Do Something
        }
    
        // or
        void func(std::vector<T>& vec, std::function<T( const std::string)> const& f){
            //Do Something
        }
    
        // or
        template<typename F> func(std::vector<T>& vec, F f){
            //Do Something
        }
    };
    
    0 讨论(0)
提交回复
热议问题