2

I need to pass a cv::Ptr as argument to a function and I am not sure how to do it. Shall I pass it by reference, or by value? I know that std::auto_ptr is pretty ugly if I pass it as value and not as reference.

So:

void foo(cv::Ptr<cv::FeatureDetector> detector) { /*...*/ }

or

void foo(cv::Ptr<cv::FeatureDetector>& detector) { /*...*/ }

?

And, if I use const, what is the difference:

void foo(const cv::Ptr<cv::FeatureDetector> detector) { /*...*/ }
void foo(const cv::Ptr<cv::FeatureDetector>& detector) { /*...*/ }

?

thedarkside ofthemoon
  • 2,251
  • 6
  • 31
  • 48

2 Answers2

4

cv::Ptr is a pointer-like type, which means it provides reference semantics. If you have a cv::Ptr that is const, it only gives you const access to the object it is pointing at. This is actually a strange quirk, because normal pointers and the standard smart pointers do not work in this way. Your choice of function depends on whether you need to be able to modify the cv::FeatureDetector.

If you need to modify it, your two choices are:

void foo(cv::Ptr<cv::FeatureDetector> detector) { /*...*/ }
void foo(cv::Ptr<cv::FeatureDetector>& detector) { /*...*/ }

The overhead of copying the cv::Ptr is likely to be minimal (or at least have no effect on your program). I typically see any non-const reference parameter as being an "output parameter", which suggests that the cv::Ptr itself is going to modified. But due to the quirkiness of cv::Ptr, what this really means is that it is allowing cv::FeatureDetector to be modified. To avoid this confusion, I would much prefer the value parameter.

I assume you're using C++03 because you mentioned std::auto_ptr, but if you ever upgrade to C++11 and if OpenCV adds a move constructor to cv::Ptr, you'll also have the benefits of move semantics.

If you want to express that the cv::FeatureDetector will not be modified, you can make the parameters const. This ensures that you do not modify the cv::FeatureDetector inside your function. Your choices are:

void foo(const cv::Ptr<cv::FeatureDetector> detector) { /*...*/ }
void foo(const cv::Ptr<cv::FeatureDetector>& detector) { /*...*/ }

This first one is really no different from the non-const value parameter from the outside.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
1

cv::Ptr is an object. See other related questions and answers like this: How to pass objects to functions in C++?

Community
  • 1
  • 1
Michele mpp Marostica
  • 2,445
  • 4
  • 29
  • 45