«Backporting» nullptr для C ++ - программы до C ++ 0x - PullRequest
9 голосов
/ 05 января 2012

Более или менее то, что предлагает название.Хотя я еще не использую 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 ]

3 голосов
/ 05 января 2012

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

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

mylibrary::nullptr_t nullptr = { };
1 голос
/ 06 января 2012

Основная причина, по которой вам не разрешено добавлять вещи в 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 (или использовать другое имя для этого типа).

...