在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)
和类似功能:
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是否也有效。
答案 0 :(得分:5)
为什么OpenCV有自己的字符串类? OpenCV是一个非常古老的图书馆(2000年6月首次发布)。那时,标准库的可靠性较差,而OpenCV团队可能认为他们宁愿自己编写。几年前,MFC团队做出了同样的决定,Qt团队和wxWidgets团队做出了同样的决定。 “字符串”类的扩散正是标准委员会定义std::string
的原因 - 但为时已晚。
如果你可以在整个项目中只使用一个字符串类,那就去吧。通常你不能;例如,给定一个返回给定一个函数,该函数通过非const引用获取cv::String
的函数,没有自动转换为std::string
。cv::String
,你需要一个实际的cv::String
对象来传递。 (编辑:Jonas指出 是从cv::String
到std::string
的自动转换。)
另请注意,您对putString
的调用实际上可能使用cv::String
- 它是通过转换构造函数从std::string
隐式构建的。如果(并且仅当)您有性能热点,那么这些不必要的转换可能是个问题。
答案 1 :(得分:3)
如果您知道构造一个字符串只能与openCV函数一起使用而且您不需要以一种奇特的方式操作它,我会使用cv::String
来避免多次转换并可能最大限度地减少依赖项的数量在项目中使用。
另一方面,如果您计划在应用程序周围使用字符串,或者您计划在将其传递给函数之前使用它,我会坚持使用std::string
标准库的算法,可以与它一起使用,同样,避免多次转换。
对我来说,如果方便的话,可以在同一个应用程序的不同部分使用这两个版本。只需对您使用它们保持一致,例如:如果您选择上述方法,请不要使用std::string
,如果其唯一目的是提供openCV功能,反之亦然。
至于为什么openCV开发人员决定拥有他们自己的字符串版本,我只能猜测,我猜他们认为即使今天的基本功能是相同的,拥有自己的版本也会为引入新版本带来新的可能性功能明天不会破坏现有代码。这是一种相当常见的设计方法来包装你自己的其他类,特别是当你正在编写一个库时,即使你的类最初没有提供额外的功能 - 只是为了让你打开门,以防你有一天想要使用不同的库实现一些功能或自己添加新功能。
答案 2 :(得分:1)
借助扩展的C ++ 11标准库,我们可以摆脱手工制作的
cv::String
和cv::Ptr
。现在cv::String == std::string
和cv::Ptr
是std::shared_ptr
之上的薄包装。