Как я могу инициализировать значение указателя Type *, используя Type () - как синтаксис? - PullRequest
14 голосов
/ 09 ноября 2011

Переменные встроенных типов можно инициализировать значениями так: :

int var = int();

таким образом, я получаю значение по умолчанию int без жесткого кодирования нуля в моем коде.

Однако, если я попытаюсь сделать аналогичные вещи для указателя:

int* ptr = int*();

компилятор (Visual C ++ 10) отказывается компилировать это (говорит type int unexpected).

Как инициализировать указатель по значению аналогичным образом?

Ответы [ 7 ]

9 голосов
/ 09 ноября 2011

Используйте typedef, чтобы создать имя для вашего типа указателя:

typedef int *ip;

ip ptr = ip();

Эта же идея должна работать для других типов, которым требуется более одного лексического элемента (слова) для определения имени типа (например, unsigned long, long long, unsigned long long * и т. д.).

4 голосов
/ 09 ноября 2011

Как инициализировать значение указателя типа * с помощью синтаксиса, подобного Type ()?

Вы не можете. Синтаксис T() определен в 5.2.3 / 1,2 (C ++ 03, немного другая формулировка в C ++ 11 FDIS). В частности, второй абзац гласит:

Выражение T (), где T - это спецификатор простого типа (7.1.5.2) для не полного массива типа объекта или типа void (возможно, cv-квалифицированного), создает значение r указанного типа, который инициализирован значением (8.5);

Это означает, что int() создаст значение типа int и value-initialize it. Теперь проблема в том, что int* - это не простой спецификатор типа, а сложный спецификатор типа. Определение спецификатора простого типа в грамматике:

  simple-type-specifier:
    ::opt nested-name-specifieropt type-name
    ::opt nested-name-specifier template template-id
    char
    wchar_t
    bool
    short
    int
    long
    signed
    unsigned
    float
    double
    void

Имя типа определяется как:

  type-name:
    class-name
    enum-name
    typedef-name

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

3 голосов
/ 09 ноября 2011

Не требует использования typedef (но только для C ++ 11), что может быть полезно при работе с несколькими типами указателей:

template<typename T>
using alias = T;

, тогда alias<int*> равно int*, так что вы можете сделать int* p = alias<int*>().

Аналогичное решение, доступное для C ++ 03, используя метафункцию идентификации:

template<typename T>
struct identity {
    typedef T type;
};

int* p = identity<int*>::type();
1 голос
/ 09 ноября 2011

Вот один из способов:

template <typename T>
T make_default()
{
    return T();
}

int main()
{
    int *p = make_default<int*>();
}
1 голос
/ 09 ноября 2011

Просто сделайте

int* x = int();

Он по-прежнему присваивает 0 указателю, что делает его указателем на адрес NULL, поскольку по умолчанию используется значение int, равное 0 в любом случае.

На самом деле, он отлично работает для всех типов:

double* y = int();

Адрес по-прежнему является 32-разрядным (или 64-разрядным, в зависимости от платформы) целым числом, поэтому я думаю, что он должен нормально работать для всех типов, если вы делаете= int ().

0 голосов
/ 09 ноября 2011

Причина, по которой это не работает, заключается в том, что у указателей нет конструкторов.

Синтаксис

int ()

вызовов (втеория)

int::int ()

, которая инициализирует переменную.(Скорее всего, компилятор просто обнуляет переменную, но это потому, что он «знает» о целых числах).

В C ++ 11 вы можете использовать nullptr

int *ptr = nullptr;

В противном случае вам в значительной степени придется использовать NULL:

int *ptr = NULL;

0 голосов
/ 09 ноября 2011

Вот как ты это делаешь int * ptr = new int;

указатели кучи

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...