【问题标题】:How to determine the result type of a C++ lambda (Closure Type)如何确定 C++ lambda 的结果类型(闭包类型)
【发布时间】:2015-02-24 04:58:44
【问题描述】:

我正在尝试编写一个可与​​std::function 或 lambda 一起使用的模板函数。让我们假设一个 apply 模板是这样的:

template<typename F>
typename F::result_type apply(const F &f) {
    return f();
}

如果我使用 std::function&lt;int()&gt; 调用它,这很好,但如果使用 []() -&gt; int { return 1; } 调用它就不行,因为 lambda 的闭包类型没有 result_type 成员。那么如何编写apply 的返回类型使其正常工作呢?

我目前正在使用 clang 3.5 和 C++14,但无论我得到什么,最好是可移植的——如果有帮助的话,我很乐意切换到更新的编译器。

实际的例子有点复杂。我正在尝试编写类似reduce 的东西,如果第一个参数是可调用的,它将将参数应用于可调用对象,否则它将忽略参数并返回作为第一个参数传递的值。

reduce(0, 1, 2); // returns 0
reduce([](int a, int b) { return a+b; }, 2, 3); // return 5

【问题讨论】:

    标签: c++ lambda functional-programming c++14


    【解决方案1】:

    对于 C++14,你应该使用decltype(auto)

    template<typename F>
    decltype(auto) apply(const F &f) {
        return f();
    }
    

    对于 C++14 之前的版本,您可以使用来自 Boost.FunctionTypesresult_type

    template<typename F>
    typename boost::function_types::result_type<F>::type apply(const F &f) {
        return f();
    }
    

    【讨论】:

    • 您在 Boost 示例的末尾没有遗漏::type 吗? typename boost::function_types::result_type&lt;F&gt;::type
    • 为什么不使用 decltype(f()) 的尾随返回类型用于 C++11 之前的版本,这样就不会依赖另一个库?
    • 因为他的问题继续说它可能不像没有参数的函数那么简单。
    • 结果有点复杂,因为我不能将decltype(auto)enable_if 和可变参数一起使用。 IE。这不编译:typename std::enable_if&lt;is_callable&lt;F&gt;::value, decltype(auto)&gt;::type apply(const F &amp;f, const P &amp;...ps)
    • 您可以为 SFINAE 使用虚拟模板参数吗?喜欢template &lt;typename F, typename = typename std::enable_if&lt;is_callable&lt;F&gt;::value&gt;::type 并单独保留decltype(auto)
    猜你喜欢
    • 2018-01-20
    • 2015-10-18
    • 1970-01-01
    • 2015-08-18
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多