为什么C ++中的types别名在其语法中使用“using”而不是“typedef”?
显然,input别名和模板types别名在语义上等同于typedefs和typedefs的扩展以支持模板。 如何using
关键字创build新的语法,而不是使用typedef作为typedef的第一个和一些语法扩展。
注意:这不是“使用和typedef之间的区别”问题的克隆。 我知道using
定义了一个typedef
的家庭的优势。 我所问的是为什么标准人员决定让这个扩展名使用using
关键字而不是typedef
关键字。 这似乎只是增加了语言的混乱。
你提出的build议实际上早在2002年由Herb Sutter在N1406号文件中提出。 这将允许,例如,写:
template<typename T> typedef X<T,int> Xi;
这后来由Gabriel Dos Reis和Mat Marcus在N1449修订。 他们采用using
语法,并注意以下几点:
请注意,我们特别避免使用“typedef模板”这个术语,并引入包含“using”和“=”的新语法来避免混淆:我们在这里没有定义任何types,我们引入了一个同义词抽象涉及模板参数的type-id(即typesexpression式)。
他们还指出:
有关语法的两项调查结果。 强大的多数投票避免typedef模板语法,赞成“=”语法。 第二次投票表明对“使用”关键字的强烈偏好,而不是如本提案草案版本中的“别名”或没有任何关键字这样的词。 使用任何关键字的动机部分源于希望使用可能与上面简要概述的非模板混叠方向兼容的语法。
这个语法在Gabriel Dos Reis和Bjarne Stroustrup的最终提案N2258中被采用。
以下是Bjarne Stroustrup谈到他们为什么using
而不是扩展typedef
:
使用的关键字是用来得到一个线性符号“名称,其次是它所指的”。 我们尝试使用传统的,复杂的typedef解决scheme,但是直到我们使用一个不太模糊的语法,才没有设法得到一个完整和一致的解决scheme。
他还声称他也喜欢这种语法,对于通常的typedef也更喜欢:
除了与模板相关的重要之外,types别名还可以用作普通types别名的不同(和更好的)语法:
using PF = void (*)(double);
他在这里相当正确,这看起来很干净。 相比之下,typedef会非常复杂,名字在中间的某个地方:
typedef void(*PF)(double);
以下是他们提出的更深入的解释 (参见第4页):
有人build议(重新)使用关键字typedef(如文章[4]所述)来引入模板别名:
template<class T> typedef std::vector<T,MyAllocator<T>> Vec;
该符号具有使用已知引入types别名的关键字的优点。 然而,它也显示了一些缺点,其中混淆了使用已知在别名不指定types的上下文中引入types名称的别名的关键字,而是使用模板;
Vec
不是一个types的别名,不应该用于typedef-name。 名称Vec
是家族std::vector<*,MyAllocator<*>>
,其中星号是types名称的占位符。 因此,我们不build议使用“typedef”语法。template<class T> using Vec = std::vector<T,MyAllocator<T>>;
可以被读取/解释为: 从现在开始,我将使用
Vect<T>
作为std::vector<T,MyAllocator<T>>
的同义词 。 通过阅读,用于别名的新语法似乎合乎逻辑。
所以他在这里基本上有两点:
-
using
模板成为一个types的家庭,而不是一个types,所以typedef
是“错误的” -
using
几乎可以看成英文句子