【问题标题】:What is the fastest method to get "const wchar_t*" from QString从 QString 获取“const wchar_t*”的最快方法是什么
【发布时间】:2014-06-01 05:33:11
【问题描述】:

我想将QString 变量传递给带有const wchar_t* 参数的函数。

安全的解决方案是:

void foo(const wchar_t*);
QString x = "test";
foo(x.toStdWString().c_str());

但它有转换为wstring 的开销。有没有更快的解决方案?

这个解决方案怎么样?安全便携吗?

foo(reinterpret_cast<const wchar_t*>(x.constData()));

【问题讨论】:

  • reinterpret_cast 实际上是潜在不安全和不可移植的定义。
  • QChar to wchar_t 的可能重复项

标签: c++ qt qstring wchar-t


【解决方案1】:

不,重新解释演员表不安全,并且在某些编码不同的平台上不起作用。 QChar 是 16 位,内部编码是 UTF-16,但在 Linux 上 wchar_t 是 32 位 UCS-4 编码。

演员会在wchar_t永远停留在16位的Windows上工作(它仍然是未定义的行为,但msc++目前没有做任何会破坏它的事情),但使用Qt的重点是可移植的,对吧?

请注意,通过std::wstring 进行的转换是尽可能高效的。鉴于编码内存的差异必须分配一次,由 std::wstring 管理(即使在 C++98 中也可以省略返回副本),std::wstring::c_str() 是一个微不足道的 getter。

【讨论】:

  • 演员阵容总是错误。 wchar_t 与 unsigned short 相同,并且不需要强制转换,或者它们是单独的类型,并且强制转换会调用非法别名(严格的别名违规,也就是类型双关语)。
  • @BenVoigt:是的。但是 msc++ 并没有基于严格的别名进行优化,我什至记得微软在某处说他们没有计划,因为他们知道有多少违反它的代码存在于野外(并且可能自己有很大一部分)。我稍微改写了这一段。
  • 最有效的方法是toWCharArray,它可以避免动态内存分配,并且不需要构造(和销毁)std::wstring 实例。
【解决方案2】:

如果x.constData 为您提供可寻址为const wchar_t* 的数据,则您不需要演员表。

任何没有强制转换就无法编译的情况,都会被严重破坏(非法别名和很可能也是不兼容的编码)。

看起来正确的方法是x.utf16()(无强制转换),即使这样也只有当wchar_t 是unsigned short。见http://qt-project.org/doc/qt-4.8/qstring.html#utf16

QString 始终是 UTF-16,所以如果wchar_t 不是,那么就没有不转换的方法。

【讨论】:

  • 不!它给出了 QChar*。和 QChar 类型定义为无符号短。
  • @A.Danesh: QChar 看起来像一个类,而不是 typedef。无论如何,请参阅stackoverflow.com/a/7360480/103167
  • -1 编辑后。重点是 QString 是 UTF-16,但 wchat_t 是 不是! 该规范的意图显然是 wchar_t 是恒定宽度编码,适用于 Unicode 3 和更高版本占用 4 个字节(3 个字节,但 3 字节类型是不切实际的),一些系统遵循这一点。事实上,Windows API 现在仍然使用 16 位 wchar_t,因为尽管将其烘焙到系统调用中。
  • 另外,QString::utf16() 确实需要转换为const wchar_t *,因为wchar_t 是不等于unsigned short 的不同类型(C++ 规范要求),除非您正在使用 MSVC++ 进行编译并设置错误兼容性选项/Zc:wchar_t-。
  • @BenVoigt:no 系统中wchar_t 是unsigned short,因为 C++ 标准要求它不是。 MSVC++ 有一个向后兼容选项/Zc:wchar_t-,它使wchar_t 成为unsigned char 的typedef,但它的存在只是为了简化古代代码的编译,默认情况下不选择,并且与您将获得的大多数库不兼容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
  • 1970-01-01
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多