I have C++98 API that takes a value by non-const reference and changes this value.
Specifically, I'm using OpenCV and the function is cv::rectangle()
which takes a cv::Mat &
image to be drawn upon.
This same API also uses expression templates to optimize image arithmetic. I can draw a rectangle on a Region-of-Interest (ROI) by creating a (non-const) temporary wrapper object that represents a sub-image.
With VS2010, I can write:
cv::Mat a(10,10,CV_8UC1); // create 10x10 image
Rect rec(0,0,2,2); // create 2x2 rectangle
cv::rectangle(a, rec, cv::Scalar::all(0)); // (1) draw 2x2 on full image
cv::rectangle(a(rec), rec, cv::Scalar::all(0)); // (2) draw 2x2 on 2x2 sub-image << !!!
This works without a problem. On line (2) a temporary sub-image wrapper object is created and passed to cv::rectangle
by reference.
However, on XCode for iOS with Clang with C++11 support, line (2) give the following error:
.../test.cpp:605:5: No matching function for call to 'rectangle'
.../core.hpp:2594:17: Candidate function not viable: expects an l-value for 1st argument
For completeness, here's the relevant prototype:
//! draws the rectangle outline or a solid rectangle covering rec in the image
CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec,
const Scalar& color, int thickness=1,
int lineType=8, int shift=0);
I think this happens because a(rec)
creates a temporary that is being passed by ref to cv::rectangle
and the compiler does not allow this temporary to be converted to an l-value. Perhaps this temporary is automatically defined as const?
I am indeed passing a temporary, but the temporary is a wrapper for an actual non-const l-value and should be allowed to change freely.
Is there a way to tell Clang to relax these constraints?
Is it somehow possible to tell the compiler that these headers are coming from a C++98 library and thus should handle temporaries like in C++98? Something akin to doing extern "C"
?
Is there a way to allow conversion of the temporary to an l-value.
Of course, I can write auto b=a(rec)
and pass b
instead, but that fills up the code with a bunch of named temporaries and beats the purpose of the wrapper classes.