bool markersFormRectangle = [](std::vector<cv::Point2f> markerCoords) {
cv::Point2f center(
(markerCoords[0].x + markerCoords[1].x + markerCoords[2].x + markerCoords[3].x) / 4,
(markerCoords[0].y + markerCoords[1].y + markerCoords[2].y + markerCoords[3].y) / 4
);
float dd1 = cv::norm(center - markerCoords[0]);
float dd2 = cv::norm(center - markerCoords[1]);
float dd3 = cv::norm(center - markerCoords[2]);
float dd4 = cv::norm(center - markerCoords[3]);
return (fabs(dd1-dd2) < 5) && (fabs(dd1 - dd3) < 5) && (fabs(dd1 - dd4) < 5);
};
我正在尝试使用上面提到的lambda表达式来检查这四个点是否形成近似矩形的形状。但编译器抱怨错误:称为对象类型&#39; bool&#39;当我尝试以下列方式在if语句中使用lambda表达式时,它不是函数或函数指针:
if (markersFormRectangle(markerPoints)) {
//do something
}
当我更改返回类型auto
时,它不会给我这个错误。我很擅长使用lambda仿函数。你能否告诉我我做错了什么以及如果类型改为auto
,编译器为什么不再给出错误?
答案 0 :(得分:5)
在此声明中
bool markersFormRectangle = [](std::vector<cv::Point2f> markerCoords)
{
cv::Point2f center((markerCoords[0].x +markerCoords[1].x + markerCoords[2].x + markerCoords[3].x) / 4,
(markerCoords[0].y +markerCoords[1].y + markerCoords[2].y + markerCoords[3].y) / 4);
float dd1 = cv::norm(center - markerCoords[0]);
float dd2 = cv::norm(center - markerCoords[1]);
float dd3 = cv::norm(center - markerCoords[2]);
float dd4 = cv::norm(center - markerCoords[3]);
return (fabs(dd1-dd2) < 5) && (fabs(dd1 - dd3) < 5) && (fabs(dd1 - dd4) < 5);
};
初始值设定项是lambda表达式,而声明的变量是bool类型。从lambda表达式的类型到类型bool
没有隐式或依赖于上下文的转换。
考虑到每个lambda都有自己独特的类型。
所以你必须写
auto markersFormRectangle = [](std::vector<cv::Point2f> markerCoords)
{
cv::Point2f center((markerCoords[0].x +markerCoords[1].x + markerCoords[2].x + markerCoords[3].x) / 4,
(markerCoords[0].y +markerCoords[1].y + markerCoords[2].y + markerCoords[3].y) / 4);
float dd1 = cv::norm(center - markerCoords[0]);
float dd2 = cv::norm(center - markerCoords[1]);
float dd3 = cv::norm(center - markerCoords[2]);
float dd4 = cv::norm(center - markerCoords[3]);
return (fabs(dd1-dd2) < 5) && (fabs(dd1 - dd3) < 5) && (fabs(dd1 - dd4) < 5);
};
来自C ++ 14标准(5.1.2 Lambda表达式)
3 lambda表达式的类型(也是表达式的类型) closure object)是一个唯一的,未命名的nonunion类类型 - 称为 闭包类型 - 其属性如下所述。这个类类型 既不是聚合(8.5.1)也不是文字类型(3.9)......
要使用尾随返回类型说明符
显式指定lambda返回类型 auto markersFormRectangle = [](std::vector<cv::Point2f> markerCoords) -> bool
{
cv::Point2f center((markerCoords[0].x +markerCoords[1].x + markerCoords[2].x + markerCoords[3].x) / 4,
(markerCoords[0].y +markerCoords[1].y + markerCoords[2].y + markerCoords[3].y) / 4);
float dd1 = cv::norm(center - markerCoords[0]);
float dd2 = cv::norm(center - markerCoords[1]);
float dd3 = cv::norm(center - markerCoords[2]);
float dd4 = cv::norm(center - markerCoords[3]);
return (fabs(dd1-dd2) < 5) && (fabs(dd1 - dd3) < 5) && (fabs(dd1 - dd4) < 5);
};
虽然没必要。
请记住(5.1.2 Lambda表达式)
7 lambda-expression的复合语句产生函数体 (8.4)函数调用运算符,...
答案 1 :(得分:3)
Lambdas只能存储在auto
类型的变量中,或者转换为函数指针(例如使用std::function
),如果你想获得lambda的结果,你需要将其称为拳头。您的代码应该是:
auto markers = []{ return true; };
bool value = markers();
或
bool value = []{ return true; }();
取决于您是否尝试存储lambda或其结果。