Какой смысл “определения типа sometype sometype”?

В последнее время я столкнулся со следующей конструкцией в коде:

typedef sometype sometype;

Обратите внимание, что "sometype" обозначает абсолютно тот же тип без любых дополнений как "структура" и т.д.

Интересно, для чего это может быть полезно?

UPD: Это работает только на определяемые пользователем типы.

UPD2: фактический код был в шаблонном контексте как это:

template <class T>
struct E
{
   typedef T T;
   ...
}
6
задан Alex Jenter 4 February 2010 в 20:43
поделиться

5 ответов

Как насчет того, чтобы сделать параметры шаблона видимыми для внешних объектов?

template <class Foo>
struct Bar
{
    typedef Foo Foo;
};

int main()
{
    Bar<int>::Foo foo = 4;
}

Примечание: это фактически не разрешено в стандартном C ++, но характерно только для MSVC. См. Комментарии.

​​
7
ответ дан 8 December 2019 в 03:52
поделиться

Теперь мы можем ответить, учитывая вашу дополнительную информацию о шаблонах.

Сценарий использования - это когда вы хотите специализироваться на типе шаблона. Вот типичный пример:

template <typename T>
struct nonconst {
    typedef T t;
};

template <typename T>
struct nonconst<T const> {
    typedef T t;
};

Это эффективно позволяет удалить квалификатор const из любого типа :

nonconst<int>::t x;
nonconst<int const>::t y;
assert(typeid(x) == typeid(int));
assert(typeid(y) == typeid(int));

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

Однако обратите внимание на другой регистр имен типов! Равные типы в typedef T T недопустимы в C ++. [Я исправляюсь: §7.1.3.2] Кроме того, фактический стандарт именования (закрепленный его использованием в библиотеках Boost) должен вызывать псевдоним имени типа type , например:

typedef T type;
7
ответ дан 8 December 2019 в 03:52
поделиться

В C ++ вы можете поместить определение типа в пространство имен или класс, а затем ссылаться на него относительно этого пространства имен или класса, что может быть полезно, если реальный тип может измениться в будущем.

например.

class IntHolder
{
    public:
        typedef int int;
        IntHolder::int i;
};
...
IntHolder foo;
IntHolder::int i = foo.i;

(NB: я не проверял, что это вполне правильный синтаксис - но, надеюсь, вы уловили идею)

Если в какой-то момент в будущем вы действительно захотите сохранить long в IntHolder , вам нужно только изменить код IntHolder .

Обычно вы называете тип по-другому, но, может быть, вы можете сделать то же самое?

6
ответ дан 8 December 2019 в 03:52
поделиться

У меня есть теория. Это могло быть результатом некоторого рефакторинга. Например, шаблонный тип становится не шаблонным.

typedef SomeCleverTemplate<Rocket> SuperThing;

Затем они удалили шаблон, так как в коде он не использовался по-другому, и на всякий случай заменили каждый SomeCleverTemplate на SuperThing .

typedef SuperThing SuperThing;

Имеет ли это смысл в реальном контексте?

6
ответ дан 8 December 2019 в 03:52
поделиться

Как уже упоминалось, он особенно хорошо работает в шаблоне:

template <class Foo>
struct Bar
{
  typedef Foo Foo;
};

Но его также можно комбинировать со специализацией шаблона:

template <class Foo>
struct Bar<Foo*>
{
  typedef Foo Foo;
};

Теперь я могу:

Bar<int>::Foo i = 0;
Bar<int*>::Foo j = i;

Бар , таким образом, эффективно ведет себя как своего рода оболочка типа, которая может быть важна для его интерфейса (например, если существует bool, равное (Foo i) const ).

Обычно выбранное имя имеет какое-то значение value_type например ...

1
ответ дан 8 December 2019 в 03:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: