2014-09-06 199 views
2

我有以下功能:lambda函数作为参数传递

template <typename Range> 
Range FindFirstIf(Range rng, bool (*Function)(typename Range::ConstReference value)) 

为了这个功能,我想传递一个lambda函数是这样的:

rng = FindFirstIf(rng, [](const float& val) { return (v < 0.0f); }); 

rng是名单的范围浮动,所以Range::ConstReference被定义为const float&

我的编译器(gcc)抱怨类型不匹配

C:\Programming\Collections\main.cpp|24|note: mismatched types 'bool (*)(typename Range::ConstReference)' and 'main(int, char**)::< lambda(const float&) >'| 

有人可以告诉我我的代码有什么问题吗?

编辑:

当我通过功能这样的,它的工作原理:

bool (*func)(const float& v) = [](const float& v) { return v < 0.0f; };

当我尝试使用auto关键字,这是同样的问题之前:

auto func = [](const float& v) { return v < 0.0f; }; 
+1

你应该检查'val',而不是'v'。 – hvd 2014-09-06 18:20:10

+0

你已经有了一个解释什么是错的答案,但是也可能有用的是一个解决方法:'rng = FindFirstIf(rng,+ [](const float&v){return(v <0.0f);});'。 '+'强制直接将lambda转换为函数指针(因为lambda类没有提供重载的“+”运算符,但提供了转换为指针的运算符,其结果是“+”可以是应用),并且GCC 4.8不会将其检测为不匹配类型。 – hvd 2014-09-07 02:32:24

+0

@hwd谢谢你真的很好的解决方法 – 2014-09-08 11:22:53

回答

2

我怀疑你的代码中是否有type-o,或者你正在使用的gcc版本没有com完全实现lambda(或可能两者)。

如果您的例子是:

[](const float& val) { return (val < 0.0f); } 

(V - > VAL)

如果Range::ConstReferenceconst float&,那么代码是合法的C++ 11。

这里棘手的部分是一些 lambdas会隐式转换为函数指针。也就是说,那些没有lambda-capture的lambda将转换为具有相同签名的函数指针。

此:

template <class Range> 
Range 
FindFirstIf(Range, bool (*Function)(typename Range::ConstReference value)); 

struct range 
{ 
    using ConstReference = const float&; 
}; 

int 
main() 
{ 
    range rng; 
    rng = FindFirstIf(rng, [](const float& val) { return (val < 0.0f); }); 
} 

编译我。

随着在线gcc编译器的一些小问题,这似乎是gcc 4.8中的一个bug,在4.9中修复。

+0

谢谢。 val-v只是一个错字,所以看起来问题出现在我的编译器版本中。 – 2014-09-06 18:27:33