mercredi 1 juillet 2015

operator << (stream output) for nullptr

Consider a piece of generic C++ code which outputs to a stream the values of its arguments in case they are not equal:

#define LOG_IF_NE(a, b) if(a != b) { \
    std::cerr << "Failed because (" << ##a << "=" << (a) << \
        ") != (" << ##b << "=" << (b) << ")"; \
}

This is just an example, the real code throws an exception after writing message to a string stream. This works fine for 2 integers, 2 pointers, etc. for what stream operator << is defined.

int g_b;
int f(int a)
{
    LOG_IF_NE(a, g_b);
    // implementation follows
}

A problem happens when one of the arguments to LOG_IF_NE is nullptr: MSVC++2013 compiler gives error C2593: 'operator <<' is ambiguous.

int *pA;
int g()
{
    LOG_IF_NE(pA, nullptr);
}

The problem happens because nullptr has a special type and operator << is not defined in the STL for that type. An answer at http://ift.tt/1CJAyzQ suggests to define operator << for std::nullptr_t

//cerr is of type std::ostream, and nullptr is of type std::nullptr_t
std::ostream& operator << (std::ostream& os, std::nullptr_t)
{
    return os << "nullptr"; //whatever you want nullptr to show up as in the console
}

Is it the right way to solve the problem? Isn't it a bug in C++11/STL that operator<< is not defined for nullptr_t? Is a fix expected in C++14/17? Or was it done on purpose (therefore one's private definition of operator<< could have a pitfall)?

Aucun commentaire:

Enregistrer un commentaire