В чем разница между "typedef" и "use" в С++ 11?

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

typedef int MyInt;

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

using MyInt = int;

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

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

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

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

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

Они по сути одинаковы, но 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

Ответ 5

Я знаю, что у оригинального плаката есть отличный ответ, но для любого, кто спотыкается в этой теме, как у меня, есть важное примечание из предложения, которое, я думаю, добавляет что-то ценное к обсуждению здесь, особенно к проблемам в комментариях относительно того, является ли ключевое слово typedef будет помечен как устаревший в будущем или удален как избыточный/старый:

Было предложено (повторно) использовать ключевое слово typedef..., чтобы ввести псевдонимы шаблона:

template<class T>
  typedef std::vector<T, MyAllocator<T> > Vec;

Преимущество этой нотации заключается в использовании уже известного ключевого слова для введения псевдонима типа. Тем не менее, он также отображает несколько недостатков [sic], среди которых путаница в использовании ключевого слова, известного как введение псевдонима для имени типа в контексте, где псевдоним не обозначает тип, но шаблон; Vec не является псевдонимом для типа и не должен восприниматься как typedef-name. Имя Vec - это имя для семейства std::vector<•, MyAllocator<•> > где пуля является заполнителем для имени типа. Следовательно, мы не предлагаем синтаксис "typedef". С другой стороны, предложение

template<class T>
  using Vec = std::vector<T, MyAllocator<T> >;

можно читать/интерпретировать как: с этого момента я буду использовать Vec<T> как синоним для std::vector<T, MyAllocator<T> >. С этим чтением новый синтаксис для псевдонимов кажется достаточно логичным.

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

Обновление ключевого слова using было специально для шаблонов, и (как было указано в принятом ответе), когда вы работаете с не-шаблонами, using и typedef механически идентичны, поэтому выбор полностью зависит от программиста на основе читабельности и сообщение о намерениях.