【问题标题】:Type deduction for std::functionstd::function 的类型推导
【发布时间】:2017-03-13 20:52:44
【问题描述】:

以下代码不会编译,因为在编译时没有调用匹配的 std::function 构造函数。

template <typename X, typename Y>
Y invoke(std::function<Y(X)> f, X x) {
    return f(x);
}

int func(char x) {
    return 2 * (x - '0');
}

int main() {
    auto val = invoke(func, '2');
    return 0;
}

但是是否可以提供与上述示例中预期的相同(或相似)的功能?有没有一种优雅的方法可以让函数接受任何 Callable:

invoke([](int x) -> int { return x/2; }, 100); //Should return int == 50

bool (*func_ptr)(double) = &someFunction;
invoke(func_ptr, 3.141); //Should return bool

?

【问题讨论】:

标签: c++ c++11 templates std-function


【解决方案1】:
#include <functional>
#include <cassert>

template <typename F, typename X>
auto invoke(F&& f, X x) -> decltype(std::forward<F>(f)(x)) {
    return std::forward<F>(f)(x);
}

int func(char x) {
    return 2 * (x - '0');
}

bool someFunction(double) {return false;}

int main() {
    auto val = invoke(func, '2');
    assert(val == 4);
    auto val2 = invoke([](int x) -> int { return x/2; }, 100);
    assert(val2 == 50);
    bool (*func_ptr)(double) = &someFunction;
    bool b = invoke(func_ptr, 3.141);
    return 0;
}

http://melpon.org/wandbox/permlink/zpkZI3sn1a76SKM8 的实时示例

【讨论】:

    【解决方案2】:

    将可调用类型作为模板参数:

    template <typename Func, typename Arg>
    auto invoke(Func&& f, Arg&& x) -> decltype(f(std::forward<Arg>(x))) {
        return f(std::forward<Arg>(x));
    }
    

    我会更进一步,为参数使用一个参数包,这样您就不会局限于单参数可调用对象:

    template <typename Func, typename... Args>
    auto invoke(Func&& f, Args&&... x) -> decltype(f(std::forward<Args>(x)...)) {
        return f(std::forward<Args>(x)...);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 1970-01-01
      相关资源
      最近更新 更多