从lambda表达式返回布尔值时出错

the*_*ive 1 c++ lambda boolean

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);
};
Run Code Online (Sandbox Code Playgroud)

我试图使用上面提到的lambda表达式来检查这四个点是否形成近似矩形的形状.但编译器抱怨错误:当我尝试在if语句中使用lambda表达式时,调用对象类型'bool'不是函数或函数指针:

if (markersFormRectangle(markerPoints)) {
    //do something
}
Run Code Online (Sandbox Code Playgroud)

当我更改返回类型时,auto它不会给我这个错误.我很擅长使用lambda仿函数.你能不能告诉我我做错了什么以及为什么编译器在类型改为auto?时不再给出错误?

Vla*_*cow 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);
        };
Run Code Online (Sandbox Code Playgroud)

初始值设定项是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);
        };
Run Code Online (Sandbox Code Playgroud)

来自C++ 14标准(5.1.2 Lambda表达式)

3 lambda-expression的类型(也是闭包对象的类型)是一个唯一的,未命名的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);
        };
Run Code Online (Sandbox Code Playgroud)

虽然没必要.

请记住(5.1.2 Lambda表达式)

7 lambda-expression的复合语句产生函数调用运算符的函数体(8.4),...