cv::String 和 std::string:什么时候使用哪一个以及两者都使用的必要性?

cv::String and std::string: When to use which one and necessity to use both?

在 OpenCV 项目中,通常 cv::String 用于函数,例如一个简单的putText。但是,当使用 std 的功能时,std::string 是负责的。例如。在这种情况下

ifstream stream(filepath);
string line;
getline(stream, line, '\n');

有必要 std::string 因为 cv::String 会抛出错误。在反之亦然的情况下,使用 OpenCV 函数 std::string 被正确转换为 cv::String 并且以下代码有效:

string Str = "Test";
putText(img, Str, Point(10, 10), FONT_HERSHEY_PLAIN, 1, Scalar::all(255), 1);

问题

为什么OpenCV有自己的String-Class?我认为可能存在一些对 OpenCV 有用的差异,而 std::string 的所有(或大部分?)功能对于 cv::String 仍然是可能的。但似乎 std::string 可以转换为 cv::String (我至少测试过 putText.

文档显示了类似的功能,但也有一些差异,例如相关功能 static bool operator> (const String &lhs, const String &rhs) 和类似的功能:

http://docs.opencv.org/3.1.0/d1/d8f/classcv_1_1String.html 对于 cv::String http://www.cplusplus.com/reference/string/string/ 对于 std::string

我是不是漏掉了什么?

为什么我应该在一个项目中使用两个版本的字符串,或者为了更好的可读性只使用 std::string 是否可以接受? (只要不使用例如前面提到的相关功能)

编辑: 这个问题 here 解决了 QString 和字符串的类似问题,建议尽可能使用 std::string。我想知道这是否也适用于 OpenCV。

如果您知道您构造的字符串仅用于 openCV 函数并且您不需要以花哨的方式操作它,我会使用 cv::String 来避免多次转换并可能最小化数字项目中使用的依赖项。

另一方面,如果您计划在整个应用程序中使用您的字符串,或者您计划在将它传递给函数之前使用它,我会坚持使用 std::string与您可以使用的标准库的所有算法一起使用,并且再次避免多次转换。

对我来说,如果方便的话,可以在同一应用程序的不同部分使用这两个版本。只要对它们的使用保持一致,例如如果您选择上述方法,请不要使用 std::string 如果它的唯一目的是服务于 openCV 功能,反之亦然。

至于为什么 openCV 开发人员决定拥有他们自己的字符串版本,我只能猜测,我猜他们认为即使今天基本功能是相同的,拥有他们自己的版本也会为明天在不破坏现有代码的情况下引入新功能。这是一种相当常见的设计方法,将其他 类 包装在您自己的内部,尤其是在您编写库时,即使您的 类 最初不提供其他功能 - 只是为了以防万一您想有一天使用不同的库来实现某些功能或自己添加新功能。

为什么OpenCV有自己的字符串class? OpenCV 是一个相当古老的库(2000 年 6 月首次发布)。那时,标准库不太可靠,OpenCV 团队可能决定他们宁愿编写自己的库。几年前,MFC 团队做出了同样的决定,Qt 团队和 wxWidgets 团队也是如此。 "string" classes 的激增正是标准委员会定义 std::string 的原因——但为时已晚。

如果您可以在整个项目中只使用一个字符串 class,那就去做吧。通常你不能;例如,给定一个 return 为 cv::String 的函数,不会自动转换为 std::string 给定一个接受 [=11] 的函数=] 通过非常量引用,你需要一个实际的 cv::String 对象来传递。 (编辑:Jonas 指出 cv::Stringstd::string 的自动转换。)

另请注意,您对 putString 的调用实际上可能使用 cv::String - 它是通过转换构造函数从 std::string 隐式构造的。如果(且仅当)您有性能热点,那些不必要的转换可能会成为问题。

changelog of OpenCV 4.0 状态:

Thanks to the extended C++11 standard library, we could get rid of hand-crafted cv::String and cv::Ptr. Now cv::String == std::string and cv::Ptr is a thin wrapper on top of std::shared_ptr.