繁体   English   中英

C++ 无法调用 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM