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.

链接地址: http://www.djcxy.com/p/73086.html

上一篇: C ++将一个对象传递给一个函数,operator =不会被调用

下一篇: C ++无法调用std :: endl