Какой смысл в "typedef sometype sometype"? - PullRequest
6 голосов
/ 04 февраля 2010

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

typedef sometype sometype;

Обратите внимание, что «sometype» означает абсолютно тот же тип без каких-либо дополнений, таких как «struct» и т. Д.

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

UPD: работает только для пользовательских типов.

UPD2: фактический код находился в контексте шаблона, например:

template <class T>
struct E
{
   typedef T T;
   ...
}

Ответы [ 6 ]

7 голосов
/ 04 февраля 2010

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

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

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 голосов
/ 04 февраля 2010

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

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

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

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

6 голосов
/ 04 февраля 2010

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

typedef SomeCleverTemplate<Rocket> SuperThing;

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

typedef SuperThing SuperThing;

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

6 голосов
/ 04 февраля 2010

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

например

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

(Примечание: я не проверил, что это правильный синтаксис - но, надеюсь, вы поняли)IntHolder вам нужно всего лишь изменить код IntHolder.

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

1 голос
/ 04 февраля 2010

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

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

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

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

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

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

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

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

0 голосов
/ 08 мая 2013

Новая идея!Некоторые клубы программирования любят широко использовать typedefs ...

zoo / animals / types.h :

namespace zoo
{
    namespace animals
    {
        typedef size_t Count;
        // ...
    } // namespace animals
} // namespace zoo

zoo / animals / zebra.h :

#include "zoo/animals/types.h"

namespace zoo
{
    namespace animals
    {
        class Zebra {
        public:
            typedef Count Count;
            Count getLegCount() const;
            // ...
        }; // class Zebra
    } // namespace animals
} // namespace zoo

main.cpp :

#include "zoo/animals/zebra.h"

int main()
{
    typedef zoo::animals::Zebra Zebra;
    Zebra z;
    Zebra::Count n = z.getLegCount();
    // Not as zoo::animals::Count
    // No using namespace zoo::animals required,
    // we are using just one item from there, the Zebra.
    // Definition of Zebra::Count may change, your usage remains robust.
    return 0;
}

У меня просто похожая ситуация на рабочем месте.Перевод может быть немного глупым, но я хотел представить его в спешке.

...