C++11 中的“typedef"和“using"有什么区别? [英] What is the difference between 'typedef' and 'using' in C++11?

查看:47
本文介绍了C++11 中的“typedef"和“using"有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在 C++11 中我们现在可以使用 using 来编写类型别名,比如 typedefs:

I know that in C++11 we can now use using to write type alias, like typedefs:

typedef int MyInt;

据我所知,相当于:

using MyInt = int;

这种新的语法是为了有一种表达模板类型定义"的方法而产生的:

And that new syntax emerged from the effort to have a way to express "template typedef":

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

但是,对于前两个非模板示例,标准中是否还有其他细微差别?例如,typedefs 在弱"代码中做别名处理.道路.也就是说,它不会创建新类型,而只会创建新名称(这些名称之间的转换是隐式的).

But, with the first two non-template examples, are there any other subtle differences in the standard? For example, typedefs do aliasing in a "weak" way. That is it does not create a new type but only a new name (conversions are implicit between those names).

using一样还是生成新的类型?有什么不同吗?

Is it the same with using or does it generate a new type? Are there any differences?

推荐答案

以下所有标准参考参考 N4659:2017 年 3 月 Kona 后工作草案/C++17 DIS.

但是,对于前两个非模板示例,标准中还有其他细微差别吗?

But, with the first two non-template examples, are there any other subtle differences in the standard?

  • 差异语义:无.
  • 差异在允许的上下文中:一些(1).
    • Differences in semantics: none.
    • Differences in allowed contexts: some(1).
    • (1) 除了别名模板的例子,在原帖中已经提到.

      (1) In addition to the examples of alias templates, which has already been mentioned in the original post.

      [dcl.typedef]/2 管辖[摘录,强调我的]

      As governed by [dcl.typedef]/2 [extract, emphasis mine]

      [dcl.typedef]/2typedef-name也可以通过介绍别名声明.using 关键字后面的 identifier 变成了typedef-nameidentifier 后面的可选 attribute-specifier-seq 属于那个 typedef-name.这样的typedef-name 与由 typedef 说明符引入的语义相同. [...]

      [dcl.typedef]/2 A typedef-name can also be introduced by an alias-declaration. The identifier following the using keyword becomes a typedef-name and the optional attribute-specifier-seq following the identifier appertains to that typedef-name. Such a typedef-name has the same semantics as if it were introduced by the typedef specifier. [...]

      别名声明引入的typedef-nametypedef<引入具有相同的语义/code> 声明.

      a typedef-name introduced by an alias-declaration has the same semantics as if it were introduced by the typedef declaration.

      然而,这并不暗示这两种变体在使用环境方面具有相同的限制.事实上,尽管是极端情况,typedef 声明 是一个 init-statement 因此可以在允许初始化语句的上下文中使用

      However, this does not imply that the two variations have the same restrictions with regard to the contexts in which they may be used. And indeed, albeit a corner case, a typedef declaration is an init-statement and may thus be used in contexts which allow initialization statements

      // C++11 (C++03) (init. statement in for loop iteration statements).
      for(typedef int Foo; Foo{} != 0;) {}
      
      // C++17 (if and switch initialization statements).
      if (typedef int Foo; true) { (void)Foo{}; }
      //  ^^^^^^^^^^^^^^^ init-statement
      
      switch(typedef int Foo; 0) { case 0: (void)Foo{}; }
      //     ^^^^^^^^^^^^^^^ init-statement
      
      // C++20 (range-based for loop initialization statements).
      std::vector<int> v{1, 2, 3};
      for(typedef int Foo; Foo f : v) { (void)f; }
      //  ^^^^^^^^^^^^^^^ init-statement
      
      for(typedef struct { int x; int y;} P;
      //  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ init-statement
          auto [x, y] : {P{1, 1}, {1, 2}, {3, 5}}) { (void)x; (void)y; }
      

      别名声明不是一个init-statement,因此不能在允许初始化语句的上下文中使用

      whereas an alias-declaration is not an init-statement, and thus may not be used in contexts which allows initialization statements

      // C++ 11.
      for(using Foo = int; Foo{} != 0;) {}
      //  ^^^^^^^^^^^^^^^ error: expected expression
      
      // C++17 (initialization expressions in switch and if statements).
      if (using Foo = int; true) { (void)Foo{}; }
      //  ^^^^^^^^^^^^^^^ error: expected expression
      
      switch(using Foo = int; 0) { case 0: (void)Foo{}; }
      //     ^^^^^^^^^^^^^^^ error: expected expression
      
      // C++20 (range-based for loop initialization statements).
      std::vector<int> v{1, 2, 3};
      for(using Foo = int; Foo f : v) { (void)f; }
      //  ^^^^^^^^^^^^^^^ error: expected expression
      

      这篇关于C++11 中的“typedef"和“using"有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆