Within an OpenCV project normally cv::String
is used in functions, e.g. a simple putText
. However, when using functions of std
std::string
is in charge. E.g. in the case
ifstream stream(filepath);
string line;
getline(stream, line, '\n');
it is necessary to have a std::string
as cv::String
throws an error. In the vice versa case using an OpenCV function std::string
is properly converted to cv::String
and following code does work:
string Str = "Test";
putText(img, Str, Point(10, 10), FONT_HERSHEY_PLAIN, 1, Scalar::all(255), 1);
Questions
Why does OpenCV has an own String-Class? I think there may be some differences useful for OpenCV, while all (or most?) functionality of std::string
is still possible for cv::String
. But it seems that std::string
can be converted to cv::String
(which I have tested at least for putText
.
The documentations show similar functions but also some differences like the related functions static bool operator> (const String &lhs, const String &rhs)
and similar:
http://docs.opencv.org/3.1.0/d1/d8f/classcv_1_1String.html for cv::String
http://www.cplusplus.com/reference/string/string/ for std::string
Am I missing something?
Is there a reason why I should use both versions of Strings in one project or would it be acceptable to only use std::string
in terms of better readability? (As long as not using e.g. the related functions mentioned earlier)
Edit:
This question here addresses a similar problem with QString and string and the recommendation is to use std::string
where possible. I wonder if this is also valid for OpenCV.
There is no functionality difference between string and std::string because they're the same type.
std::string is compatible with STL algorithms and other containers. C strings are not char * or const char * ; they are just null-terminated character arrays. Even string literals are just character arrays.
Because the declaration of class string is in the namespace std. Thus you either need to always access it via std::string (then you don't need to have using) or do it as you did. Save this answer.
string class is part of C++ library that supports a lot much functionality over C style strings. C++ string class internally uses char array to store character but all memory management, allocation, and null termination is handled by string class itself that is why it is easy to use.
Why does OpenCV have its own string class? OpenCV is a pretty old library (first release June 2000). At that point, standard libraries were less reliable, and the OpenCV team probably decided they would rather write their own. The MFC team made the same decision a few years earlier, as did the Qt team and the wxWidgets team. This proliferation of "string" classes is exactly why the standards committee defined std::string
- but it was too late.
If you can get away with using just one string class throughout the project - go for it. Often you can't; for example, given a function which return a given a function which takes a cv::String
, there is no automatic conversion to std::string
.cv::String
by non-const reference, you need an actual cv::String
object to pass. (Edit: Jonas points out that there is an automatic conversion from cv::String
to std::string
.)
Also note that your call to putString
may actually use a cv::String
- it is implicitly constructed from std::string
via the converting constructor. If (and only if) you have a performance hot-spot, those unnecessary conversions may be a problem.
If you know that you construct a string to use it with openCV functions only and you don't need to manipulate it in a fancy way, I would use cv::String
to avoid multiple casting and possibly minimizing number of dependencies used in project.
If, on the other hand, you are planning to use your string all around your application or you are planning to play with it before passing it to a function, I would stick to std::string
as it comes with all the algorithms of the standard library that you can use with it, and, again, to avoid multiple casting.
To me it's ok to use both versions in different parts of the same application if it's convenient. Just be consistent about your usage of them, e.g. if you choose the above approach, don't use std::string
if its sole purpose is to serve openCV functions and vice versa.
As for why openCV developers decided to have their own version of string, I can only guess, and I would guess that they assumed that even if today the basic functionality is the same, having their own version opens new possibilites for introducing new features without breaking already existing code tomorrow. It's a fairly common design approach to wrap other classes within your own, especially when you are writing a library, even if your classes initially don't offer additional functions - just to leave the door open in case you wanted to use different library one day to implement some features or adding new ones by yourself.
The changelog of OpenCV 4.0 states:
Thanks to the extended C++11 standard library, we could get rid of hand-crafted
cv::String
andcv::Ptr
. Nowcv::String == std::string
andcv::Ptr
is a thin wrapper on top ofstd::shared_ptr
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With