1

I'm having problem in compilation of the following code snippet while using GNU g++ 4.9.2 (used to compile ok in g++ 2.95.3)

XOStream &operator<<(ostream &(*f)(ostream &))  {
        if(f == std::endl) {
                *this << "\n" << flush;
        }
        else {
                ostr << f;
        }
        return(*this);
}

The error is as below:

error: assuming cast to type 'std::basic_ostream<char>& (*)(std::basic_ostream<char>&)' from overloaded function [-fpermissive]
     [exec]    if(f == std::endl) {
     [exec]                 ^

Please guide/help.

Dr. Debasish Jana
  • 6,980
  • 4
  • 30
  • 69
  • Note: To avoid running into this kind of problems you may write a XOStreamBuffer and attach it to the XOStream (being an almost unchanged ostream) –  Jun 08 '16 at 12:09
  • So, why are you not just letting `endl` do its thing? Because you want to intercept `flush` at the `XOStream` level instead of at the `ostr` level? You could also simplify the `else` to `return f(ostr);` directly... I guess if it too is doing a similar hack, that won't work. – Yakk - Adam Nevraumont Jun 08 '16 at 20:07

2 Answers2

3

Select the overload of std::endl with a static_cast:

#include <iostream>
#include <iomanip>

inline bool is_endl(std::ostream &(*f)(std::ostream &)) {
    // return (f == static_cast<std::ostream &(*)(std::ostream &)>(std::endl));
    // Even nicer (Thanks M.M)
    return (f == static_cast<decltype(f)>(std::endl));
}

int main()
{
    std::cout << std::boolalpha;
    std::cout << is_endl(std::endl) << '\n';
    std::cout << is_endl(std::flush) << '\n';
}
2

std::endl is a function template, you need to specify the template arguments. Because you're using std::ostream (i.e. basic_ostream<char>) you could

if (f == endl<char, std::char_traits<char>>)
songyuanyao
  • 169,198
  • 16
  • 310
  • 405