C ++无法调用std :: endl
改善问题的框架:
有一个记录器C ++类,其中<<操作符被重载以接受整数,字符串..
logR <<"Test"<<endl
现在,endl被定义为宏
#define endl "nr"
现在在任何.cpp文件中,如果我包含此记录器类的头文件,我曾使用endl编译错误。
找到了一个解决方案,而不是定义宏endl,我重载运算符来接收endl()本身。 感谢您帮助解决问题的投入。
从标准N4687:
20.5.4.3.2宏名称
1包含标准库头的翻译单元不得在任何标准库头中声明的#define或#undef名称 。
2翻译单位不得#将#define或#undef在词汇上与关键字相同的名称,表4中列出的标识符或10.6中描述的属性标记。
所以你试图做的是标准所禁止的!
另外在这个特定的情况下,它不会工作,因为你用endl
代替了某种类型的字符串,导致预处理器产生这个: std::"nr"
,导致编译失败。
如果你不想用"rn"
替换std::endl
(顺便说一下:不是"nr"
),那么可以手动或者编写脚本来完成。
正如已经指出的那样,你不能用名字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] = "nr";
观察到的行为应该与使用宏相同,只是该声明可以与std::endl
共存。 这确实假设你不使用我认为很古怪的L endl
。 想想看,我可以想象你正在使用T(endl)
,它几乎增加了这个L
但是可以连接L
到名字。 如果是这样,你还可以添加
extern wchar_t const Lendl[];
与相应的定义。
如果你想使用你的endl
就像std::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');
}
当然,当向文本模式下打开的std::ofstream
(或std::wofstream
)发送一个'n'
字符(即,不使用std::ios_base::binary
)时,它会被翻译成[platform specific ]行尾序列。
上一篇: C++ unable to call std::endl
下一篇: Cout is not a member of std, and other issues regarding c++