В чем разница между typedef и using в C ++ 11?

597

Я знаю, что в С++ 11 мы теперь можем использовать using для записи псевдонима типа, например typedef s:

typedef int MyInt;

Я понимаю, что, как я понимаю, эквивалентно:

using MyInt = int;

И этот новый синтаксис возник из стремления выразить "template typedef":

template< class T > using MyType = AnotherType< T, MyAllocatorType >;

Но с первыми двумя примерами, отличными от шаблонов, существуют ли какие-либо другие тонкие различия в стандарте? Например, typedef делает сглаживание "слабым" способом. То есть он не создает новый тип, а только новое имя (конверсии неявны между этими именами).

То же самое с using или он генерирует новый тип? Существуют ли какие-либо различия?

  • 181
    Я лично предпочитаю новый синтаксис, потому что он намного больше похож на обычное назначение переменных, улучшая читабельность. Например, вы предпочитаете typedef void (&MyFunc)(int,int); или using MyFunc = void(int,int); ?
  • 9
    Я полностью согласен, я использую только новый синтаксис сейчас. Вот почему я спрашивал, чтобы убедиться, что на самом деле нет разницы.
Показать ещё 8 комментариев
Теги:
c++11
typedef
using-declaration

3 ответа

367
Лучший ответ

Они эквивалентны из стандартного (акцент мой) (7.1.3.2):

Имя typedef также может быть введено с помощью объявления alias. идентификатор после ключевого слова using становится typedef-name и необязательный атрибут-спецификатор-seq, следующий за идентификатором. к этому typedef-name. Он имеет ту же семантику, как если бы это было введенный спецификатором typedef. В частности, это не определяет новый тип и не будет отображаться в идентификаторе типа.

  • 22
    Исходя из ответа, using ключевого слова является надмножеством typedef . Тогда будет ли typdef устаревшим в будущем?
  • 6
    @iammilind, вероятно, нет, но вы можете кодировать, как если бы это было.
Показать ещё 7 комментариев
140

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

template <typename T> struct whatever {};

template <typename T> struct rebind
{
  typedef whatever<T> type; // to make it possible to substitue the whatever in future.
};

rebind<int>::type variable;

template <typename U> struct bar { typename rebind<U>::type _var_member; }

Но синтаксис с использованием упрощает этот прецедент.

template <typename T> using my_type = whatever<T>;

my_type<int> variable;
template <typename U> struct baz { my_type<U> _var_member; }
  • 29
    Я уже указал это в вопросе, хотя. Мой вопрос о том, если вы не используете шаблон, есть ли разница с typedef. Как, например, когда вы используете 'Foo foo {init_value};' вместо 'Foo foo (init_value)' оба должны делать одно и то же, но не следуют одним и тем же правилам. Поэтому мне было интересно, была ли похожая скрытая разница с использованием / typedef.
84

Они во многом одинаковы, за исключением того, что

The alias declaration is compatible with templates, whereas the C style typedef is not.

  • 23
    Особенно любит простоту ответа и указание на происхождение шрифта.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню