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


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

typedef int MyInt;

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

using MyInt = int;

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

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

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

то же самое с using или он генерирует новый тип? Есть ли различия?

4 693

4 ответа:

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

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

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

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; }

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

объявление псевдонима совместимо с шаблонами, тогда как C определение типа, стиля нет.

они по сути одинаковы, но using предоставляет alias templates что весьма полезно. Один хороший пример я мог бы найти следующим образом:

namespace std {
 template<typename T> using add_const_t = typename add_const<T>::type;
}

Итак, мы можем использовать std::add_const_t<T> вместо typename std::add_const<T>::type