"Backporting" nullptr для C++- программы до C++0x

Более или менее то, что предлагает название. Хотя я еще не использую C++0x, я хотел бы быть готовым к тому, когда это произойдет, и я также хотел бы уменьшить объем кода, который мне нужно переписать, чтобы использовать некоторые его возможности. Таким образом, я могу получить обратную и прямую совместимость за один раз.

Один из самых интересных, которые я нашел, это nullptr, который я использую чаще всего в последнее время.

Проверив "Официальный обходной путь" и предложение Майера, я решил, что хотел бы использовать это и в моих программах на C++, и в будущих программах на C++0x. Вторая часть проста - быть ключевым словом, nullptr будет просто поддерживаться. Но первая часть вызывает у меня некоторый дискомфорт.

Предложение Мейерса работает следующим образом:

class nullptr_t { // ← this is my issue
    // definition of nullptr_t
} nullptr = { };

Проблема с этим предложением состоит в том, что оно объявляет тип, который будет объявлен как std::nullptr_t в соответствии с требованиями C++0x. Что означает, что для обходного пути "чувствовать себя родным" это должно быть сделано путем повторного открытия std:: Пространство имен для добавления типа. У меня есть понимание, что нельзя делать в программе на C++ (в отличие от добавления специализаций, которые, по-видимому, являются недовольными и предупреждающими).

Я хочу использовать nullptr в удобной и законной форме в программе на C++. Одним из вариантов, о котором я подумал, было объявление типа в другом пространстве имен, а затем его использование using:

namespace mylibrary {
class nullptr_t {
    ....
} nullptr = { };
// end namespace
}

// These would have to go in the header file.
using mylibrary::nullptr;
using mylibrary::nullptr_t; // apparently this is necessary as well?

Будет ли это правильный способ заставить его работать? Это заставит using директивы, что также вызывает определенный порядок #include директивы, а также. Правильно ли ожидать, что никакой код до C++0x не будет запрашивать тип nullptr_t с пространством имен (как тип аргумента функции, например)? Будет ли это действительно работать "чувствовать себя родным", если это будет сделано таким образом?


Как дополнение, приветствуется или не одобряется попытка перенести некоторые изящные C++0x вещи в C++ для лучшей совместимости и кодирования? Тем временем я интегрировал это решение и другие, над которыми работаю, в часть программного обеспечения, которое будет выпущено.

2 ответа

Решение

Основная причина, по которой вам не разрешено добавлять namespace std так что вы не испортите вещи, которые уже есть. В противном случае это легко сделать. В прошлом я обнаружил несколько определений операторов вывода для контейнеров, для которых был создан встроенный тип, например std::vector<int>, Тем не мение, nullptr_t не определен в этом пространстве имен и добавление typedef должен быть довольно безобидным. То есть я бы определил nullptr_t в другом пространстве имен, чем namespace std а затем добавить typedef за nullptr_t в namespace std, Переменная nullptr В любом случае необходимо объявить его в глобальной области видимости, поскольку он используется неквалифицированным в C++2011.

Ли тип std::nullptr_t Требуется зависит от того, заинтересованы ли вы в добавлении подписей с использованием этого типа. Например, std::shared_ptr<T> можно сравнить с nullptr, Для этого необходимо добавить подходящие перегрузки с указанием типа std::nullptr_t (или используйте другое имя для этого типа).

Если вы не можете придумать причину, вам нужно объявить другой объект типа nullptr_t (Я не могу), я бы спрятал тип и убрал nullptr в глобальном пространстве имен, чтобы максимально точно имитировать ключевое слово:

namespace mylibrary
{
    class nullptr_t
    {
        ....
    };
}

mylibrary::nullptr_t nullptr = { };
Другие вопросы по тегам