C ++ 11中的'typedef'和'using'有什么区别?

本文翻译自:What is the difference between 'typedef' and 'using' in C++11?

I know that in C++11 we can now use using to write type alias, like typedef s: 我知道在C ++ 11中,我们现在可以使用using来编写类型别名,例如typedef

typedef int MyInt;

Is, from what I understand, equivalent to: 据我了解,相当于:

using MyInt = int;

And that new syntax emerged from the effort to have a way to express " template typedef ": 并且,这种新语法是通过努力表达“ template typedef ”的方式而出现的:

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

But, with the first two non-template examples, are there any other subtle differences in the standard? 但是,对于前两个非模板示例,标准中是否还有其他细微差别? For example, typedef s do aliasing in a "weak" way. 例如, typedef会以“弱”方式进行别名。 That is it does not create a new type but only a new name (conversions are implicit between those names). 也就是说,它不会创建新的类型,而只会创建一个新名称(这些名称之间的转换是隐式的)。

Is it the same with using or does it generate a new type? 是否与using相同或会生成新类型? Are there any differences? 有什么区别吗?


#1楼

参考:https://stackoom.com/question/j5zm/C-中的-typedef-和-using-有什么区别


#2楼

They are equivalent, from the standard (emphasis mine) (7.1.3.2): 它们与标准(强调我的)(7.1.3.2)是等效的:

A typedef-name can also be introduced by an alias-declaration. typedef名称也可以通过别名声明来引入。 The identifier following the using keyword becomes a typedef-name and the optional attribute-specifier-seq following the identifier appertains to that typedef-name. using关键字后面的标识符变为typedef名称,而标识符后面的可选attribute-specifier-seq属于该typedef名称。 It has the same semantics as if it were introduced by the typedef specifier. 它具有与typedef说明符引入的语义相同的语义。 In particular, it does not define a new type and it shall not appear in the type-id. 特别是,它没有定义新的类型,也不应出现在type-id中。


#3楼

The using syntax has an advantage when used within templates. 在模板中使用时, using语法具有优势。 If you need the type abstraction, but also need to keep template parameter to be possible to be specified in future. 如果需要类型抽象,还需要保留模板参数,以便将来可以指定。 You should write something like this. 你应该这样写。

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

But using syntax simplifies this use case. 但是使用语法可以简化此用例。

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

my_type<int> variable;
template <typename U> struct baz { my_type<U> _var_member; }

#4楼

They are largely the same, except that: 它们基本相同,除了:

The alias declaration is compatible with templates, whereas the C style typedef is not. 别名声明与模板兼容,而C风格的typedef不兼容。


#5楼

They are essentially the same but using provides alias templates which is quite useful. 它们本质上是相同的,但是using提供了非常有用的alias templates One good example I could find is as follows: 我可以找到一个很好的例子,如下所示:

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

So, we can use std::add_const_t<T> instead of typename std::add_const<T>::type 因此,我们可以使用std::add_const_t<T>代替typename std::add_const<T>::type


#6楼

I know the original poster has a great answer, but for anyone stumbling on this thread like I have there's an important note from the proposal that I think adds something of value to the discussion here, particularly to concerns in the comments about if the typedef keyword is going to be marked as deprecated in the future, or removed for being redundant/old: 我知道原始发帖人的回答很好,但是对于像我这样绊脚石的任何人,提案中都有一条重要说明,我认为这对此处的讨论特别是对typedef关键字是否在注释中的关注增加了一些价值。将来将被标记为已弃用,或由于冗余/旧而被删除:

It has been suggested to (re)use the keyword typedef ... to introduce template aliases: 已建议(重新)使用关键字typedef ...引入模板别名:

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

That notation has the advantage of using a keyword already known to introduce a type alias. 该符号的优点是使用已知的关键字来引入类型别名。 However, it also displays several disavantages [sic] among which the confusion of using a keyword known to introduce an alias for a type-name in a context where the alias does not designate a type, but a template; 但是,它也显示了一些不足之处,其中在别名不是指定类型而是模板的情况下,使用已知为类型名称引入别名的关键字会造成混淆。 Vec is not an alias for a type, and should not be taken for a typedef-name. Vec 不是类型的别名,并且不应将其用作typedef名称。 The name Vec is a name for the family std::vector<•, MyAllocator<•> > – where the bullet is a placeholder for a type-name.Consequently we do not propose the “typedef” syntax.On the other hand the sentence Vec名称是std::vector<•, MyAllocator<•> >家族的名称–项目符号是类型名称的占位符。因此,我们不建议使用“ typedef”语法。句子

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

can be read/interpreted as: from now on, I'll be using Vec<T> as a synonym for std::vector<T, MyAllocator<T> > . 可以理解为: 从现在开始,我将使用Vec<T>作为std::vector<T, MyAllocator<T> >的同义词 With that reading, the new syntax for aliasing seems reasonably logical. 通过阅读,别名的新语法似乎是合理的。

To me, this implies continued support for the typedef keyword in C++ because it can still make code more readable and understandable . 对我来说,这意味着将继续支持C ++中的typedef关键字,因为它仍然可以使代码更具可读性和可理解性

Updating the using keyword was specifically for templates, and (as was pointed out in the accepted answer) when you are working with non-templates using and typedef are mechanically identical, so the choice is totally up to the programmer on the grounds of readability and communication of intent. 更新using关键字是专门为模板,并(在接受的答案指出)当你与非模板工作usingtypedef是机械上相同的,所以在选择完全取决于可读性的理由和程序员目的沟通。

发布了0 篇原创文章 · 获赞 75 · 访问量 56万+

猜你喜欢

转载自blog.csdn.net/w36680130/article/details/105386556