Reputation: 3064
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);
};
I am trying to use the above stated lambda expressions which checks if the four points form a near rectangular shape. But the compiler complains with the error: called object type 'bool' is not a function or function pointer when I try to use the lambda expression in an if statement the following way:
if (markersFormRectangle(markerPoints)) {
//do something
}
When I change the return type auto
it doesn't give me that error. I'm pretty new to using lambda functors. Could you please tell me what I am doing wrong and why the compiler doesn't give anymore error if the type is changed to auto
?
Upvotes: 1
Views: 157
Reputation: 311048
In this declaration
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);
};
the initializer is a lambda expression while the declared variable has the type bool. There is no implicit or context-dependent conversion from the type of a lambda expression to the type bool
.
Take into account that each lambda has its own unique type.
So you have to write
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);
};
From the C++14 Standard (5.1.2 Lambda expressions)
3 The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type — called the closure type — whose properties are described below. This class type is neither an aggregate (8.5.1) nor a literal type (3.9)....
To specify explicitly the lambda return type you could write using the trailing return type specifier
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);
};
though it unnecessary.
Bear in mind that (5.1.2 Lambda expressions)
7 The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator,...
Upvotes: 5
Reputation: 36459
Lambdas can only be stored in a variable of type auto
or converted to a function pointer (e.g. using std::function
), if you want to get the result of your lambda you need to call it fist. Your code should be either:
auto markers = []{ return true; };
bool value = markers();
or
bool value = []{ return true; }();
depending on whether you are trying to store the lambda or its result.
Upvotes: 3