【发布时间】:2015-02-06 06:58:53
【问题描述】:
我已经为std::ctype<char16_t> 的每个虚拟成员函数编写了自己的特化,所以现在可以使用:
#include <string>
#include <locale>
#include "char16_facets.h" // Header containing my ctype specialisation
#include <sstream>
#include <iostream>
// Implemented elsewhere using iconv
std::string Convert(std::basic_string<char16_t>);
int main() {
std::basic_string<char16_t> s("Hello, world.");
std::basic_stringstream<char16_t> ss(s);
ss.imbue(std::locale(ss.getloc(), new std::ctype<char16_t>()));
std::basic_string<char16_t> t;
ss >> t;
std::cout << Convert(t) << " ";
ss >> t;
std::cout << Convert(t) << std::endl;
}
有没有办法让流默认使用新的 ctype 特化,这样我就不必为每个流 imbue 使用新的语言环境了?
我还没有写新的类,只是提供了
template<>
inline bool std::ctype<char16_t>::do_is (std::ctype_base::mask m, char16_t c) const {
等等。我有点希望它会被自动拾取,只要它在我 #include <sstream> 之前声明,但它不是。
上面的大部分工作都是使用 G++ 和 libstdc++ 4.8 完成的,但我从 SVN 主干构建它们得到了相同的结果。
编辑 - 更新 这个问题最初询问如何让数字提取工作。但是,给定一个包含正确的ctype 和numpunct 实现的流,则不需要专门化num_get;简单的
ss.imbue(std::locale(ss.getloc(), new std::num_get<char16_t>()));
它适用于任一 gcc 版本。
再一次,有没有办法让流自动接收它,而不是让每个流都灌输它?
【问题讨论】:
-
std::locale::global(std::locale(), new std::ctype<char16_t>()); -
就这样 - 谢谢。另一个问题 - 这是否取代了全球语言环境的现有 ctype
方面?或者这是否意味着全局语言环境将具有两个 ctype 方面,并且将使用适合流类型的一个?我猜是后者,因为它有效,但我在任何地方都找不到它的文档。 -
它替换了全局语言环境中的
std::ctypefacet。我无法解释为什么它会像你刚才描述的那样工作。 -
是吗?根据en.cppreference.com/w/cpp/locale/locale,“经典”语言环境始终至少包含 ctype
和 ctype ;为什么不能在此之上添加另一个 ctype? -
对不起,我弄错了。您的
std::ctype<char16_t>专业化引入了一个新的facet 系列,因此不会替换std::ctype<char>或std::ctype<wchar_t>facet,因为它们都有不同的facet 标识。因此,您的代码将起作用,因为流的字符类型是char16_t,因此它将使用您专门化并融入全局语言环境的std::ctype<char16_t>方面。
标签: c++ unicode locale iostream facet