C++ std::function cannot find correct overload

后端 未结 3 640
闹比i
闹比i 2021-02-07 12:19

Consider the following case:

void Set(const std::function &fn);
void Set(const std::function &fn);
3条回答
  •  盖世英雄少女心
    2021-02-07 12:55

    I would suggest this solution. It should work with lambdas as well as with function-objects. It can be extended to make it work for function pointer as well (just go through the link provided at the bottom)

    Framework:

    template 
    struct function_traits : public function_traits
    {};
    
    template 
    struct function_traits
    {
        enum { arity = sizeof...(Args) };
    };
    
    template
    struct count_arg : std::enable_if::arity==NArgs, int>
    {};
    

    Usage:

    template
    typename count_arg::type Set(Functor f) 
    {
        std::function fn = f;
        std::cout << "f with one argument" << std::endl;
    }
    
    template
    typename count_arg::type Set(Functor f)
    {
        std::function fn = f;
        std::cout << "f with two arguments" << std::endl;
    }
    
    int main() {
            Set([](int a){});
            Set([](int a, int b){});
            return 0;
    }
    

    Output:

    f with one argument
    f with two arguments
    

    I took some help from the accepted answer of this topic:

    • Is it possible to figure out the parameter type and return type of a lambda?

    Work around for Visual Studio 2010

    Since Microsoft Visual Studio 2010 doesn't support variadic templates, then the framework-part can be implemented as:

    template 
    struct function_traits : public function_traits
    {};
    
    template 
    struct function_traits { enum { arity = 1 }; };
    
    template 
    struct function_traits { enum { arity = 2 }; };
    
    template 
    struct function_traits { enum { arity = 3 }; };
    
    //this is same as before 
    template
    struct count_arg : std::enable_if::arity==NArgs, ReturnType>
    {};
    

    EDIT
    Now this code supports any return type.

提交回复
热议问题