【问题标题】:Return the same type as a lambda expression passed as argument返回与作为参数传递的 lambda 表达式相同的类型
【发布时间】:2014-05-13 10:27:14
【问题描述】:

我想创建一个同时接受函数指针和 lambda 表达式的函数。函数的返回类型应该和函数指针/lambda表达式的返回类型一致。

以下是一个按预期工作但仅适用于函数指针的函数的最小示例。我也可以使用模板来接受 lambda 表达式吗?

template <typename R>
R foo(R (*func)())
{
    return func();
}

以下内容适用于函数指针和 lambda 表达式,但仅接受 bool

bool foo(std::function<bool()> func)
{
    return func();
}

bool a = foo( [](){ return true; } );

我尝试使用模板使其具有通用性,但在调用它时出现编译器错误(没有匹配的函数)

template <typename R>
R foo(std::function<R()> func)
{
    return func();
}

bool a = foo( [](){ return true; } );

【问题讨论】:

  • 没有捕获的 Lambda 可以转换为函数指针
  • @sp2danny:是的,但前提是您有该转换的上下文。这里的第一个问题是你不知道它将转换成的函数指针类型。

标签: c++ templates c++11 lambda


【解决方案1】:

你可以使用推导返回类型:

template <typename F>
auto foo(F f) -> decltype(f())
{
    return f();
}

如果F 接受一些参数:

template <typename F, typename ... Args>
auto foo(F f, Args&&...args) -> decltype(f(std::forward<Args>(args)...))
{
    return f(std::forward<Args>(args)...);
}

【讨论】:

  • 谢谢。可以扩展此解决方案以支持将参数传递给 f 吗?例如。 R foo(R (*f)(T), T x) { return f(x); }
  • @SamOlesen:是的,可以扩展解决方案以支持 args:请参阅编辑。
  • 如果“f”采用未在“foo”参数列表中列出的参数怎么办?
  • @ARA1307:这里的decltype 使用允许SFINAE,使用无效(或缺失)参数的foo 重载将不会参与。你会像预期的那样出现错误。
【解决方案2】:

这是decltype 的工作:

template <typename F>
auto foo(F f) -> decltype(f()) 
{
}

【讨论】:

    猜你喜欢
    • 2019-08-15
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多