C++ std :: function找不到正确的重载

Cem*_*ncu 14 c++ lambda c++11

考虑以下情况:

void Set(const std::function<void(int)> &fn);
void Set(const std::function<void(int, int)> &fn);
Run Code Online (Sandbox Code Playgroud)

现在调用函数

Set([](int a) {
    //...
});
Run Code Online (Sandbox Code Playgroud)

给"重载函数的模糊调用"错误.我正在使用Visual Studio 2010.是否有工作或其他方法来实现类似的东西.我不能使用模板,因为这些函数存储起来供以后使用,因为在这种情况下我无法确定参数的数量.如果你问我可以提交更多细节.

Naw*_*waz 12

我会建议这个解决方案.它应该与lambdas以及函数对象一起使用.它可以扩展,使其适用于函数指针(只需通过底部提供的链接)

框架:

template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())>
{};

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
{
    enum { arity = sizeof...(Args) };
};

template<typename Functor, size_t NArgs>
struct count_arg : std::enable_if<function_traits<Functor>::arity==NArgs, int>
{};
Run Code Online (Sandbox Code Playgroud)

用法:

template<typename Functor>
typename count_arg<Functor, 1>::type Set(Functor f) 
{
    std::function<void(int)> fn = f;
    std::cout << "f with one argument" << std::endl;
}

template<typename Functor>
typename count_arg<Functor, 2>::type Set(Functor f)
{
    std::function<void(int, int)> fn = f;
    std::cout << "f with two arguments" << std::endl;
}

int main() {
        Set([](int a){});
        Set([](int a, int b){});
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

f with one argument
f with two arguments
Run Code Online (Sandbox Code Playgroud)

我从这个主题的接受答案中得到了一些帮助:


解决Visual Studio 2010的问题

由于Microsoft Visual Studio 2010不支持可变参数模板,因此框架部分可以实现为:

template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())>
{};

template <typename C, typename R, typename T0>
struct function_traits<R(C::*)(T0) const> { enum { arity = 1 }; };

template <typename C, typename R, typename T0, typename T1>
struct function_traits<R(C::*)(T0,T1) const> { enum { arity = 2 }; };

template <typename C, typename R, typename T0, typename T1, typename T2>
struct function_traits<R(C::*)(T0,T1,T2) const> { enum { arity = 3 }; };

//this is same as before 
template<typename Functor, size_t NArgs, typename ReturnType=void>
struct count_arg : std::enable_if<function_traits<Functor>::arity==NArgs, ReturnType>
{};
Run Code Online (Sandbox Code Playgroud)

编辑
现在此代码支持任何返回类型.