Boost 根据typedef可以输出的通用cout

Boost 根据typedef可以输出的通用cout,boost,typedef,boost-mpl,c++,Boost,Typedef,Boost Mpl,C++,我有一个typedef char\u t也可以是typedef wchar\u t char\u t,我想要的是一个通用的cout 我有一个util名称空间,我想要一个util::cout如果char\t是char和std::wcout如果char\t是wchar\t你正在重新创造一个可怕的世界(至少在此时此刻,也许在某一点上这是一个好的决定)女士设计 请注意,其他平台都很可能使用UTF-8进行输出,因此通过std::cout的UTF-8字符串可以正常输出。在windows上,控制台上的Unic

我有一个
typedef char\u t
也可以是
typedef wchar\u t char\u t
,我想要的是一个通用的
cout


我有一个
util
名称空间,我想要一个
util::cout
如果
char\t
char
std::wcout
如果
char\t
wchar\t

你正在重新创造一个可怕的世界(至少在此时此刻,也许在某一点上这是一个好的决定)女士设计

请注意,其他平台都很可能使用UTF-8进行输出,因此通过
std::cout
的UTF-8字符串可以正常输出。在windows上,控制台上的Unicode输出无论如何都是不可能正确的(由于字体和中断的控制台代码页)


简而言之,没有理由想要这样的东西,你最好使用其中一个,而不是两个;您可以通过模板专门化来实现这一点,模板专门化包含对适当对象的
静态
引用

template<typename T> struct select_cout;

template<> struct select_cout<char> { static std::ostream &cout; };
std::ostream &select_cout<char>::cout = std::cout;

template<> struct select_cout<wchar_t> { static std::wostream &cout; };
std::wostream &select_cout<wchar_t>::cout = std::wcout;

std::basic_ostream<char_t> &cout = select_cout<char_t>::cout;
template struct select\u cout;
模板结构select_cout{static std::ostream&cout;};
std::ostream&select_cout::cout=std::cout;
模板结构select_cout{static std::wostream&cout;};
std::wostream&选择_cout::cout=std::wcout;
std::basic_ostream&cout=选择_cout::cout;

如果您正在读取宽格式的文件,并使用我从评论中获取的多字节程序,那么解决方案可能是

您可以将文件内容作为
std::wstring
读取到程序内存中,并使用
wcstombs_s()
将从文件中读取的字符串转换为多字节字符串


本质上,字符串的格式并不重要,您可以随时根据需要在何时何地更改它。

让一个包含输出流typedef的“template”traits类怎么样?默认情况下,它将typedef设置为cout,然后您可以为wchar\t添加一个专门化,其中typedef设置为wcout。但问题是
cout
wcout
都不是类型。很难做到的是,不同的模板重载将有不同的对象。哦,我没有意识到这一点。然后,您可以有一个内联函数根据专门化返回对cout或wcout的引用。或者按照ecatmur的建议使用静态指针。问题是我还需要解析unicode文件。因此,在Linux中,我可以使用
std::string
,在Windows Iam中,我可以使用
std::wstring
,而我不能在cout上使用wstring。编译会有问题。@NeelBasu您应该能够嵌入您的输入流,以便它返回UTF-8。或者你可以在任何地方使用UTF-16/UTF-32(并使用正确的编码)。你所说的“糟糕的设计”是使用UTF-16吗?是的,事后诸葛亮是20/20,但似乎每天都有更糟糕的决定。你对这个问题的实际解决方案是什么?你如何编写在Windows上运行的代码?@Cody:不,糟糕的设计是整个
TCHAR
mess和API函数定义依赖于
UNICODE
(或者是
\u UNICODE
,或者两者兼而有之?)。UTF-16比UTF-8没有问题。虽然UTF-32与UTF-8/16相比有一些优点和缺点。我编写代码的方法是在内部使用
std::string
作为UTF-8(尽管我没有过多考虑unicode),在应用程序/Windows API边界使用
MultiByteToWideChar
API进行转换,并专门调用
*W
函数。这包括对命令行参数使用Windows API调用。总之,一个非常薄的兼容层IMHO。@rubenvb你是对的,是的,我在考虑类似的东西,但没有常量和*。你为什么在这里使用
指针?@NeelBasu好的一点是,引用同样有效,而且更清晰。修正了。@NeelBasu好吧,如果你把它放在一个标题中,显然你必须把声明和定义分开。