【问题标题】:C++11 type inference with lambda and std::function使用 lambda 和 std::function 进行 C++11 类型推断
【发布时间】:2012-07-05 12:10:55
【问题描述】:

我有以下 sn-p 的代码,虽然完全微不足道,但说明了我试图在更通用的代码中使用的模式。

template<typename InT, typename ResT>
ResT unary_apply( InT val, std::function<ResT(InT)> fn )
{
    return fn(val);
}

我希望能够使用函数指针、函子、lambda 等调用 unary_apply:因此使用 std::function 将其抽象化。

当我尝试通过以下方式使用上述内容时,C++ (g++ 4.7) 无法执行相关类型推断:

double blah = unary_apply( 2, []( int v ) { return 3.0 * v; } );

失败

src/fun.cpp:147:75: error: no matching function for call to ‘unary_apply(int, test()::<lambda(int)>)’
src/fun.cpp:147:75: note: candidate is:
src/fun.cpp:137:6: note: template<class InT, class ResT> ResT unary_apply(InT, std::function<ResT(InT)>)
src/fun.cpp:137:6: note:   template argument deduction/substitution failed:
src/fun.cpp:147:75: note:   ‘test()::<lambda(int)>’ is not derived from ‘std::function<ResT(double)>’

而且我发现我必须明确指定模板参数(实际上我认为它只是无法推断的返回类型):

double blah = unary_apply<int, double>( 2, []( int v ) { return 3.0 * v; } );

我对 C++11 中的类型推断规则不太熟悉,但上述行为似乎是合理的(我可以看到通过 std::function 的内部机制进行推断可能是一个很大的问题)。我的问题是:是否可以重写上面的unary_applyfunction 以保持相同的灵活性(就可以作为第二个参数传递的函数/函子等类型而言)同时也提供更多线索类型推断,所以我不必在调用点显式提供模板参数?

【问题讨论】:

    标签: c++ lambda c++11 type-inference


    【解决方案1】:

    更多的鸭式应该可以工作:

    template <typename T, typename F>
    auto unary_apply(T&& val, F&& func) -> decltype(func(val)) {
        return func(std::forward<T>(val));
    }
    

    【讨论】:

    • 建议的解决方案是正确的,第一句话是不正确的。无法在问题中应用类型推断的原因与它是 lambda 的事实无关(您可以传递任何其他仿函数/函数,但它仍然无法推断类型)
    • @DavidRodríguez-dribeas:再读一遍。 Lambda 不是 function 类型。这是operator() 的未命名类类型。但是,是的,std::function&lt;R(T)&gt; 的推理可能无论如何都行不通。
    • 我错过了那部分,更正了评论:问题不在于它是一个 lambda,而是 std::function 的模板参数处于不可还原的上下文中,请尝试传递一个常规函数(不是 @987654325 @ -- 或者你的意思是 *lambda 不是 std::function 实例化?)
    • 这确实可以解决问题。非常感谢。您能否推荐任何在线资源来解释模板和 decltype 的推理规则之间的区别?
    • @AlexWilson:这里的问题不在于模板或decltype 的推理规则可能不同,而在于它的使用方式。模板需要类型的完美匹配(仅允许使用 const-volatile 限定符),在您的情况下,该函数采用 std::function&lt;?&gt; 但参数是 lambda。 std::function&lt;&gt; 可以由包括 lambda 在内的不同事物构造而成,但它们是不同的类型,需要在该上下文中进行不允许的转换。在decltype 的情况下,F 的类型被推断为 lambda 的类型。
    猜你喜欢
    • 1970-01-01
    • 2012-04-17
    • 2016-12-14
    • 2022-01-02
    • 1970-01-01
    相关资源
    最近更新 更多