模板类型定义的新"using"语法解决了什么问题?

What was the issue solved by the new "using" syntax for template typedefs?

本文关键字:解决 什么 问题 语法 using 定义 类型      更新时间:2023-10-16

在 C++11 中,您可以通过执行以下操作来创建"类型别名"

template <typename T>
using stringpair = std::pair<std::string, T>;

但这与您期望的模板 typedef 的外观有所不同:

template <typename T>
typedef std::pair<std::string, T> stringpair;

所以这就提出了一个问题 - 为什么他们需要想出一个新的语法? 什么不适用于旧的typedef语法?

我知道最后一位无法编译,但为什么不能编译?

我只提一下stroustrup本人:

http://www.stroustrup.com/C++11FAQ.html#template-alias

关键字 using 用于获取线性表示法"名称后跟 它指的是什么。我们尝试了传统和复杂的 Typedef 解决方案,但从未设法获得完整且连贯的解决方案 解决方案,直到我们确定了一个不那么晦涩的语法。

来自 WG21 提案 N1489 模板别名(由 Stroustrup 和 Dos Reis 提供):

有人建议(重新)使用关键字typedef,就像在 论文 [4] 介绍模板别名:

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

该表示法的优点是使用已知 引入类型别名。但是,它也显示了几个缺点 其中使用已知关键字引入的混淆 别名未指定的上下文中的类型名称的别名 类型,但模板;Vec 不是类型的别名,也不应 被当作一个类型定义名称。Vec这个名字是这个家庭的名字 项目符号占位符std::vector<o, MyAllocator<o> > 作为类型名称。因此,我们不建议 typedef 语法。

另一方面,这句话

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

可以阅读/解释为:从现在开始,我将使用 Vec<T> 作为 std::vector<T, MyAllocator<T> >的同义词 .有了这个读数, 别名的新语法似乎合乎逻辑。

上述引文中提到的论文[4]是先前的提案WG21 N1406提议添加到C++:Typedef模板(由Herb Sutter提供)。它使用不同的语法(typedef vs using)以及不同的命名法(typedef模板与模板别名)。赫伯提出的语法没有成功,但有时可以在非正式讨论中找到命名法。

(tl;dr: using 支持模板,而typedef不支持。


听起来您已经知道,没有模板的两个示例之间的区别不大:

[C++11: 7.1.3/2]: typedef-name 也可以通过别名声明来引入。using 关键字后面的标识符将成为 typedef-name,标识符后面的可选属性说明符 seq 对应于该 typedef-name它具有与typedef说明符引入的语义相同的语义。特别是,它不会定义新类型,并且不应出现在类型ID中。

但是,模板typedef不存在!

[C++11: 14.5.7/1]: 声明为别名声明模板声明(第 7 条)将标识符声明为别名模板。别名模板是一系列类型的名称。别名模板的名称是模板名称

他们为什么不简单地重用typedef语法?好吧,我认为typedef只是"旧"样式,并且考虑到在其他上下文中使用using,决定新功能应采用using形式以保持一致性。

新语法的另一个原因 - 函数、数组和类似结构的 typedefs 变得更加易于理解。

对数组之前/之后的引用:

typedef int(&my_type)[3];
using my_type = int(&)[3];

之前/之后的函数指针数组:

typedef void(*my_type[3])();
using my_type = void(*[3])();
相关文章: