C++ unable to call std::endl
Framed the question better manner:
Have a logger C++ class which has the << operator overloaded to accept ints, strings..
logR <<"Test"<<endl
Now the endl had been defined as macro
#define endl "nr"
Now in any .cpp file if i included this logger class's header file i used to get compilation error for using endl.
Found a fix for this instead of defining macro endl, I overloaded operator to receive the endl() itself. Thanks for the inputs it helped in solving the issue.
From the standard N4687:
20.5.4.3.2 Macro names
1 A translation unit that includes a standard library header shall not #define or #undef names declared in any standard library header .
2 A translation unit shall not #define or #undef names lexically identical to keywords, to the identifiers listed in Table 4, or to the attribute-tokens described in 10.6.
So what you are trying to do is prohibited by the standard!
Additionally in this specific case it won't work because you are substituting endl
for a string of some sort, causing the preprocessor to generate this: std::"nr"
which causes the compilation to fail.
If you wan't to replace std::endl
by "rn"
(BTW: not "nr"
) then do it by hand or write a script to do it.
As was pointed out already, you are not allowed to define a macro with the name endl
. However, you are allowed to declare a varaiable with the name endl
(outside namespace std
obviously). So you could have
// 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";
The observed behavior should be the same as using the macro except that this declaration can coexist with std::endl
. That does assume that you don''t use L endl
with which I'd consider rather odd. Thinking of it, I can imagine you are using T(endl)
which nearly adds this L
but accually concatenates L
to the name. If so, you'd just also add
extern wchar_t const Lendl[];
with a corresponding definition.
If you want to use your endl
just like std::endl
is used but with some different behavior, I'd recommend defining it in a similar way, too:
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');
}
Of course, when sending a 'n'
character to a std::ofstream
(or an std::wofstream
) opened in text mode (ie, without using std::ios_base::binary
) it gets translated into the [platform specific] end of line sequence.
上一篇: C ++将一个对象传递给一个函数,operator =不会被调用
下一篇: C ++无法调用std :: endl