cv :: String和std :: string:何时使用哪一个并且必须同时使用?

时间:2017-08-24 08:00:16

标签: c++ string opencv std

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

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

必须让std::stringcv::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)和类似功能:

cv::String的{​​p> http://docs.opencv.org/3.1.0/d1/d8f/classcv_1_1String.html std::string

http://www.cplusplus.com/reference/string/string/

我错过了什么吗?

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

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

3 个答案:

答案 0 :(得分:5)

为什么OpenCV有自己的字符串类? OpenCV是一个非常古老的图书馆(2000年6月首次发布)。那时,标准库的可靠性较差,而OpenCV团队可能认为他们宁愿自己编写。几年前,MFC团队做出了同样的决定,Qt团队和wxWidgets团队做出了同样的决定。 “字符串”类的扩散正是标准委员会定义std::string的原因 - 但为时已晚。

如果你可以在整个项目中只使用一个字符串类,那就去吧。通常你不能;例如,给定一个返回cv::String的函数,没有自动转换为std::string给定一个函数,该函数通过非const引用获取cv::String ,你需要一个实际的cv::String对象来传递。 (编辑:Jonas指出 是从cv::Stringstd::string的自动转换。)

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

答案 1 :(得分:3)

如果您知道构造一个字符串只能与openCV函数一起使用而且您不需要以一种奇特的方式操作它,我会使用cv::String来避免多次转换并可能最大限度地减少依赖项的数量在项目中使用。

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

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

至于为什么openCV开发人员决定拥有他们自己的字符串版本,我只能猜测,我猜他们认为即使今天的基本功能是相同的,拥有自己的版本也会为引入新版本带来新的可能性功能明天不会破坏现有代码。这是一种相当常见的设计方法来包装你自己的其他类,特别是当你正在编写一个库时,即使你的类最初没有提供额外的功能 - 只是为了让你打开门,以防你有一天想要使用不同的库实现一些功能或自己添加新功能。

答案 2 :(得分:1)

changelog of OpenCV 4.0指出:

  

借助扩展的C ++ 11标准库,我们可以摆脱手工制作的cv::Stringcv::Ptr。现在cv::String == std::stringcv::Ptrstd::shared_ptr之上的薄包装。