![](/img/trans.png)
[英]C++ How to implement: myInstance << "abc" << someInt << std::endl
[英]C++ unable to call std::endl
以更好的方式提出问题:
有一个记录器 C++ 类,它重载了 << 运算符以接受整数、字符串..
logR <<"Test"<<endl
现在 endl 已被定义为宏
#define endl "\n\r"
现在在任何 .cpp 文件中,如果我包含这个记录器类的头文件,我曾经因为使用 endl 而出现编译错误。
找到了解决此问题的方法,而不是定义宏 endl,我重载了运算符以接收 endl() 本身。 感谢它帮助解决问题的输入。
来自标准N4687 :
20.5.4.3.2 宏名称
1 包含标准库头文件的翻译单元不应在任何标准库头文件中声明#define 或#undef 名称。
2 翻译单元不应#define 或#undef 名称在词汇上与关键字、表4 中列出的标识符或10.6 中描述的属性标记相同。
所以你试图做的事情是标准禁止的!
此外,在这种特定情况下,它不起作用,因为您正在用endl
替换某种字符串,导致预处理器生成以下内容: std::"\\n\\r"
导致编译失败。
如果您不想将std::endl
替换为"\\r\\n"
(顺便说一句:不是"\\n\\r"
),请手动执行或编写脚本来执行此操作。
正如已经指出的那样,您不能定义名为endl
的宏。 但是,您可以声明一个名为endl
的变量(显然在命名空间std
之外)。 所以你可以有
// where the macro is currently define:
extern char const endl[3];
// in a suitable source file including the header with the above declaration:
char const endl[3] = "\n\r";
观察到的行为应该与使用宏相同,只是这个声明可以与std::endl
共存。 这确实假设您不使用我认为很奇怪的L endl
。 考虑一下,我可以想象您正在使用T(endl)
,它几乎添加了这个L
但准确地将L
连接到名称。 如果是这样,你也只需添加
extern wchar_t const Lendl[];
有相应的定义。
如果你想像使用std::endl
一样使用你的endl
但有一些不同的行为,我建议你也以类似的方式定义它:
template <typename cT, typename Traits>
std::basic_ostream<cT, Traits>& endl(std::basic_ostream<cT, Traits>& out) {
return out << out.widen('\n') << out.widen('\r');
}
当然,当将'\\n'
字符发送到以文本模式(即,不使用std::ios_base::binary
)打开的std::ofstream
(或std::wofstream
)时,它会被翻译成 [平台特定的] 行尾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.