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

typedef int MyInt;

据我了解,相当于:
using MyInt = int;

并且这种新语法是通过努力表达“template typedef”的方式而出现的:
template< class T > using MyType = AnotherType< T, MyAllocatorType >;

但是,对于前两个非模板示例,标准中是否还有其他细微差别?例如,typedef以“弱”方式进行别名。也就是说,它不会创建新的类型,而只会创建一个新名称(这些名称之间的转换是隐式的)。
using是否相同或会生成新类型?有什么区别吗?

最佳答案

以下所有标准引用均引用N4659: March 2017 post-Kona working draft/C++17 DIS

可以将Typedef声明用作别名,而不能将别名声明用作初始化语句

  • 语义上的差异:无。
  • 在允许的上下文中的差异:some(1)。

  • (1)除了别名模板的示异常(exception),该模板已在原始帖子中提到。
    相同的语义
    根据[dcl.typedef]/2的规定[摘录,强调我的]

    由别名声明引入的typedef名称具有相同的语义,就好像它是由typedef声明引入的一样。
    允许的上下文中的细微差异
    但是,这不是而不是,这暗示着这两种变体具有相同的限制。 ,可以在其中使用上下文。实际上,尽管有一个极端的情况,但typedef declarationinit-statement,因此可以在允许初始化语句的上下文中使用
    // 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; }
    
    alias-declaration而不是initt语句,因此不能在允许初始化语句的上下文中使用
    // 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++ - 在C++ 11中 'typedef'和 'using'有什么区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24260541/

    10-11 22:44
    查看更多