我正在尝试确定从std :: string构造QVariant的最有效方法,并让它存在于std :: vector中。我现在正在做:
std::string foo = "test";
std::vector<QVariant> variants;
...
variants[0] = QString::fromStdString(foo);
这种方法似乎构造了一个临时的QString,然后在调用QVariant(const QString &)
c'tor后销毁它。
有什么方法可以避免临时QString?
答案 0 :(得分:8)
register std::string
类型,然后转换为QString
将会过时。
// in some header file
Q_DECLARE_METATYPE (std::string)
// in main function
qRegisterMetaType<std::string>("std::string");
答案 1 :(得分:2)
如果你确实想存储QString
,那么由于Qt的写时复制语义,临时QString对象与性能无关。从std::string
到QString
进行文本解码将占主导地位,并且由于COW无论如何都不会复制数据(除非修改)。如果std::string
为'\0'
- 已终止的文字,则您只需使用this QVariant constructor,这可能与QString
的最佳效果相同:
variants.emplace(0, QVariant(stdstr.c_str());
替代解决方案是将std::string
存储为QByteArray
而不是QString
。如果需要复制std::string
数据,您需要决定的一件事是。如果您知道指向字符串数据的指针在QByteArray
的生命周期内仍然有效,则可以使用this:
// warning, does not copy string data, so pointer to it must remain valid
variants.emplace(0, QByteArray::fromRawData(stdstr.data(), stdstr.size()));
更安全是this,它复制但没有文字解码:
variants.emplace(0, QByteArray(stdstr.data(), stdstr.size()));
请注意std::string
并不关心编码,而是8位,所以实际上QByteArray
是它的Qt对应物。 QString
在内部存储Unicode文本UTF-16,因此无论std::string
内容的编码如何,都始终需要进行转换。
此外,您应该阅读std::string::data()
和std::vector::emplace()
个引用。
答案 2 :(得分:1)
有什么方法可以避免临时QString?
疑。
即使将QString传递给QVariant构造函数,它也会复制。
但它并不重要,因为QStrings是隐含共享的,所以复制它们是O(1)操作
虽然您可以将字符串存储为void*
,但如果您需要,它不会自动转换为字符串。