定义函数时,lambda函数/表达式是什么类型的?

S.H*_*S.H 2 c++ lambda c++11

我想定义一个函数,它接受一个lambda函数(除了通常的输入参数).我想尽可能地限制该函数(它自己的输入和返回类型).

int myfunc( const int a, LAMBDA_TYPE (int, int) -> int mylamda )
{
    return mylambda( a, a ) * 2;
}
Run Code Online (Sandbox Code Playgroud)

这样我可以调用函数如下:

int input = 5;
myfunc( input, [](int a, int b) { return a*b; } );
Run Code Online (Sandbox Code Playgroud)

定义的正确方法是myfunc什么?

有没有办法定义默认的lambda?像这样:

int myfunc( const int a, LAMBDA_TYPE = [](int a, int b) { return a*b; });
Run Code Online (Sandbox Code Playgroud)

Yak*_*ont 7

如果你拿它std::function<int(int,int)>会有开销,但它会做你想要的.它甚至可以在C++ 14中正确过载.

如果您不希望类型擦除和分配开销,std::function您可以这样做:

template<
  class F,
  class R=std::result_of_t<F&(int,int)>,
  class=std::enable_if_t<std::is_same<int,R>{}>
>
int myfunc( const int a, F&& f )
Run Code Online (Sandbox Code Playgroud)

或检查可转换性int而不是相同性.这是sfinae解决方案. 1

这将适当地过载.为简洁起见,我使用了一些C++ 14功能.替换blah_t<?>typename blah<?>::type在C++ 11.

另一种选择是static_assert类似的条款.这会生成最佳错误消息.

最后你可以使用它:如果它不能像你使用它那样使用,代码将无法编译.

在C++ 1z概念中,将有更简单/更少的代码沙拉方式来实现sfinae解决方案.


1在某些编译器上std::result_of,sfinae无法发挥作用.在那些,替换它decltype(std::declval<F&>()(1,1)).除非您的编译器不支持C++ 11(如msvc 2013和2015),否则这将起作用.(幸运的是2013/3015很不错result_of).