我知道在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声明用作别名,而不能将别名声明用作初始化语句
(1)除了别名模板的示异常(exception),该模板已在原始帖子中提到。
相同的语义
根据[dcl.typedef]/2的规定[摘录,强调我的]
由别名声明引入的typedef名称具有相同的语义,就好像它是由
typedef
声明引入的一样。允许的上下文中的细微差异
但是,这不是而不是,这暗示着这两种变体具有相同的限制。 ,可以在其中使用上下文。实际上,尽管有一个极端的情况,但typedef declaration是init-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/