Можно ли эмулировать nullptr в GCC? - PullRequest
47 голосов
/ 10 марта 2010

Я видел, что nullptr был реализован в Visual Studio 2010. Мне нравится концепция, и я хочу начать использовать ее как можно скорее; однако GCC пока не поддерживает это. Мой код должен работать на обоих (но не должен компилироваться с другими компиляторами).

Есть ли способ "подражать" этому? Что-то вроде:

#define nullptr NULL

(Очевидно, что это вообще не сработает, просто чтобы показать, что я имею в виду.)

Ответы [ 5 ]

61 голосов
/ 10 марта 2010

Официальное предложение имеет обходной путь -

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
9 голосов
/ 17 ноября 2010

Похоже, что gcc поддерживает nullptr с 4.6 .

6 голосов
/ 30 июня 2011

Кроме того, gcc (на самом деле g ++) имеет расширение __null в течение многих лет. Это было учтено как опыт внедрения в отрасли, когда вышло предложение nullptr.

Расширение __null может обнаруживать особые случаи и предупреждать о них, например, о случайной передаче NULL параметру bool, когда он должен был быть передан параметру указателя (изменения, внесенные в функцию, забыли адаптировать сторону вызова).

Конечно, это не портативно. Приведенное выше шаблонное решение является переносимым.

5 голосов
/ 01 декабря 2011

Это выглядит по gcc 4.6.1 (Ubuntu 11.11 oneiric), был добавлен nullptr.

Быстрый, рекурсивный метод поиска и замены sed в моих файлах hpp / cpp работал нормально:

find . -name "*.[hc]pp" | xargs sed -i 's/NULL/nullptr/g'
2 голосов
/ 28 июня 2012

Скорее всего, вы забыли -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 не является типом и не поддерживается для использования с:

SizeOf

TypeId

throw nullptr

На самом деле в VC2010 все вышеперечисленные операторы / выражения являются законными. sizeof (nullptr) результат 4. typeid.name () результат std :: nullptr_t, а throw nullptr может быть перехвачен "const void *" и "void *" (и другими типами указателей).

Хотя gcc (4.7.1) выглядит более жестко в отношении nullptr, throw nullptr не может быть пойман "void *", может быть пойман '...'

...