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

typedef int MyInt;

在我看来,相当于:

using MyInt = int;

新语法的出现是为了有一种表达“template typedef”的方法:

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

但是,对于前两个非模板示例,标准中还有其他细微的差异吗?例如,typedef以一种“弱”的方式进行混叠。也就是说,它不创建新类型,而只创建新名称(这些名称之间的转换是隐式的)。

它和使用是一样的还是生成一个新的类型?有什么不同吗?


当前回答

它们在很大程度上是相同的,除了:

别名声明与模板兼容,而C 样式typedef则不是。

其他回答

它们在很大程度上是相同的,除了:

别名声明与模板兼容,而C 样式typedef则不是。

到目前为止,c++ 23将typedef和using更紧密地结合在一起:P2360建议使用构成初始化语句,例如@dfrib的回答中列出的那些作为error: expected表达式。

然而,即使使用P2360,类型定义也不能是模板。

(编辑[2022-09-14]:信息不正确。)

总的来说,using严格来说比typedef更强大,而且在我看来可读性也更好。

我知道最初的海报有一个很好的答案,但对于任何像我一样在这个话题上跌跌撞撞的人来说,提案中有一个重要的说明,我认为它为这里的讨论增加了一些有价值的东西,特别是评论中关于typedef关键字是否将在未来被标记为已弃用,或因冗余/旧而被删除的问题:

It has been suggested to (re)use the keyword typedef ... to introduce template aliases: 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. 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 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> >. With that reading, the new syntax for aliasing seems reasonably logical.

对我来说,这意味着在c++中继续支持typedef关键字,因为它仍然可以使代码更具可读性和可理解性。

更新using关键字是专门针对模板的,并且(正如在已接受的答案中指出的那样)当您使用非模板时,using和typedef在机械上是相同的,因此,基于可读性和意图的交流,选择完全取决于程序员。

这两个关键字是等价的,但有一些注意事项。一种是声明函数指针使用T = int (*)(int, int);比使用typedef int (*T)(int, int)更清晰。其次,模板别名形式不可能使用typedef。第三,公开C API需要在公共头中使用类型定义。

它们本质上是相同的,但使用别名模板是非常有用的。我能找到的一个很好的例子如下:

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