Можно ли эмулировать nullptr в GCC?
Я видел это nullptr
была реализована в Visual Studio 2010. Мне нравится концепция и я хочу начать использовать ее как можно скорее; однако GCC пока не поддерживает это. Мой код должен работать на обоих (но не должен компилироваться с другими компиляторами).
Есть ли способ "подражать" этому? Что-то вроде:
#define nullptr NULL
(Это, очевидно, не очень хорошо работает, это просто чтобы показать, что я имею в виду.)
5 ответов
Официальное предложение имеет обходной путь -
const // this is a const object...
class {
public:
template<class T> // convertible to any type
operator T*() const // of null non-member
{ return 0; } // pointer...
template<class C, class T> // or any type of null
operator T C::*() const // member pointer...
{ return 0; }
private:
void operator&() const; // whose address can't be taken
} nullptr = {}; // and whose name is nullptr
Кроме того, gcc (на самом деле g++) имеет расширение __null в течение многих лет. Это было посчитано как опыт внедрения в отрасли, когда появилось предложение nullptr.
Расширение __null может обнаруживать особые случаи и предупреждать о них, например, о случайной передаче NULL параметру bool, когда он должен был быть передан параметру указателя (изменения, внесенные в функцию, забыли адаптировать сторону вызова).
Конечно, это не портативно. Приведенное выше шаблонное решение является переносимым.
Похоже на gcc 4.6.1 (Ubuntu 11.11 oneiric), был добавлен nullptr.
Быстрый, рекурсивный метод поиска и замены в моих файлах hpp/cpp отлично работал:
find . -name "*.[hc]pp" | xargs sed -i 's/NULL/nullptr/g'
Скорее всего, вы забыли -std= C++0x . Моя версия gcc для Mingw - 4.6.1/4.7.1, обе хорошо поддерживают nullptr.
Согласно описанию в "Стандартной библиотеке C++, учебник и справочник, 2-й", nullptr является ключевым словом, может автоматически преобразовываться в каждый тип указателя, но не в целочисленный тип, это устраняет недостаток NULL, который неоднозначен для следующей функции перегрузки: void f(int); void f(void *);
F (NULL); // Неоднозначный f(nullptr); // ХОРОШО
Проверка этой функции в VC2010 показывает, что документ MSDN конфликтует с фактическим компилятором, в документе сказано:
Ключевое слово nullptr не является типом и не поддерживается для использования с:
размер
TypeId
бросить nullptr
На самом деле в VC2010 все вышеперечисленные операторы / выражения являются законными. sizeof(nullptr) result 4. typeid.name() result std::nullptr_t, а throw nullptr может быть перехвачен "const void *" и "void *"(и другими типами указателей).
В то время как gcc(4.7.1) выглядит более жестко в отношении nullptr, throw nullptr не может быть пойман "void *", может быть пойман '...'