Идеально эмулировать nullptr

Я устал ждать поддержки компилятором nullptr (gcc 4.6 поддерживает, но это поэтому несколько новых дистрибутивов поддерживают его).

Поэтому в качестве временного интервала до тех пор, пока nullptr не будет полностью поддерживаться, я решил подражать ему. Есть два примера эмуляции: один из здесь и один из викикниги.

Следует отметить, что ни в одной из реализаций не упоминается operator ==. Однако без него следующий код не будет компилироваться.

int* ptr = nullptr;
assert( ptr == nullptr ); // error here: missing operator ==

Является ли эта ошибка operator == ошибкой компилятора?
Нужен ли operator ==!=, <, <= и т. д.) для более совершенной имитации nullptr?
Чем еще отличается эмулируемый nullptr от реального?


person deft_code    schedule 07.06.2011    source источник
comment
Почему бы вам сделать это вместо assert(ptr); в первую очередь?   -  person ildjarn    schedule 07.06.2011
comment
@ Нил Баттерворт: это неправда. nullptr должен быть частью Стандарта, потому что он имеет значение только тогда, когда все используют один и тот же тип нулевого указателя — std::nullptr_t. Если бы каждый реализовал свой собственный нулевой указатель, как бы вы написали функцию, которая принимала бы нулевой указатель? Вы не знаете, что такое нулевой тип указателя.   -  person Puppy    schedule 07.06.2011
comment
@ildjarn: я использовал утверждение для очистки кода. Мой фактический пример был std::remove( v.begin(), v.end(), nullptr );, который использует оператор равенства. И причина, по которой я не буду использовать std::remove_if, заключается в том, что я этого не хочу. Я хочу, чтобы он работал как настоящий nullptr.   -  person deft_code    schedule 07.06.2011
comment
Честно говоря, я не думал о последствиях в стандартной библиотеке.   -  person ildjarn    schedule 08.06.2011


Ответы (3)


Вы скомпилировали его с помощью компилятора C++0x, который не удалось выполнить по неизвестной причине. Он прекрасно компилируется в C++03.

person Yakov Galka    schedule 07.06.2011
comment
Итак, вернемся к моему первоначальному вопросу. Является ли эта ошибка следствием новых правил языка c++0x? Или это ошибка, появившаяся в gcc, когда были добавлены другие функции С++ 0x? - person deft_code; 07.06.2011
comment
@deft_code: 1) ваш код недействителен C++0x, потому что он использует ключевое слово nullptr. 2) я на 90% уверен, что это ошибка GCC 3) уже был аналогичная ошибка. - person Yakov Galka; 07.06.2011
comment
Отличная находка с этой ошибкой. Мой точный случай ошибки указан в комментариях. В ответ на пункт 1 я должен сказать нет, черт возьми! Это явно недопустимо в полностью совместимом компиляторе c++0x. gcc 4.5 еще не полностью совместим, и, следовательно, мне нужно эмулировать ключевое слово. - person deft_code; 07.06.2011

Да, вы должны реализовать такую ​​​​вещь. Я, однако, удивлен, что операторы неявного преобразования не срабатывают и не позволяют сравнивать без явного оператора.

template<typename T> bool operator==(T* ptr, nullptr_t null) {
    return ptr == 0;
}
template<typename C, typename R> bool operator==(R C::* ptr, nullptr_t null) {
    return ptr == 0;
}
// And the reverse
person Puppy    schedule 07.06.2011

На самом деле это упоминается в официальном предложении из вашего первого примера:

Эксперименты с несколькими популярными существующими компиляторами показывают, что он генерирует плохие и/или вводящие в заблуждение диагностические данные компилятора для нескольких распространенных случаев использования, описанных в разделе 2. существует функция из «const class » в «int»; «аргумент шаблона не может ссылаться на безымянный тип»; «ни один оператор «==» не соответствует этим операндам, типы операндов: int == const class ».) Мы считаем что компиляторам по-прежнему придется добавлять специальные знания о nullptr, чтобы обеспечить качественную диагностику для обычных случаев использования.

Поэтому вы должны заполнить этот пробел самостоятельно, если компилятор еще этого не сделал.

person littleadv    schedule 07.06.2011
comment
Это плохое обсуждение диагностики компилятора относится к безымянному типу nullptr. Однако комитет по стандартам решил, что nullptr будет иметь тип nullptr_t. Все эти загадочные сообщения об ошибках становятся намного лучше, когда класс nullptr называется nullptr_t. - person deft_code; 07.06.2011