Рассмотрим фрагмент универсального кода C++, который выводит в поток значения своих аргументов, если они не равны:
#define LOG_IF_NE(a, b) if(a != b) { \
std::cerr << "Failed because (" << ##a << "=" << (a) << \
") != (" << ##b << "=" << (b) << ")"; \
}
Это просто пример, реальный код выдает исключение после записи сообщения в строковый поток. Это отлично работает для 2 целых чисел, 2 указателей и т. д., для которых определен поток operator <<
.
int g_b;
int f(int a)
{
LOG_IF_NE(a, g_b);
// implementation follows
}
Проблема возникает, когда один из аргументов LOG_IF_NE
равен nullptr
: компилятор MSVC++2013 дает error C2593: 'operator <<' is ambiguous
.
int *pA;
int g()
{
LOG_IF_NE(pA, nullptr);
}
Проблема возникает из-за того, что nullptr
имеет специальный тип, а operator <<
не определено в STL для этого типа. Ответ на https://stackoverflow.com/a/21772973/1915854 предлагает определить operator <<
для 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
}
Это правильный путь решения проблемы? Разве это не ошибка в C++11/STL, что operator<<
не определено для nullptr_t
? Ожидается ли исправление в C++ 14/17? Или это было сделано намеренно (поэтому частное определение operator<<
могло иметь ловушку)?
const nullptr_t
01.07.2015