为什么C++中的类型别名在语法中使用'using'而不是'typedef'?

toh*_*ava 36 c++ templates typedef using c++11

显然,类型别名和模板化类型别名在语义上等同于typedef,并且是typedef的扩展,以支持模板.为什么using为这些创建了关键字的新语法,而不是使用typedef作为第一个和一些语法扩展的单词typedef.

注意:这不是"使用和typedef之间的区别"问题的克隆.我知道这样可以using定义一个typedefs 族.我要问的是,为什么标准人员决定使用此using关键字而不是typedef关键字.这似乎只会增加语言的混乱.

gex*_*ide 43

以下是Bjarne Stroustrup所说的为什么他们介绍using而不是扩展typedef:

关键字using用于获取线性表示法"名称后跟其引用的内容".我们尝试使用传统的和复杂的typedef解决方案,但在我们确定一个不那么模糊的语法之前,我们从未设法获得完整且连贯的解决方案.

他还声称他对通常的typedef更喜欢这种语法:

除了与模板相关的重要内容之外,类型别名还可以用作普通类型别名的不同(和IMO更好)语法:

using PF = void (*)(double);
Run Code Online (Sandbox Code Playgroud)

他在这里非常正确,这看起来很干净.相比之下,typedef会非常错综复杂,名称位于中间的某个位置:

typedef void(*PF)(double);
Run Code Online (Sandbox Code Playgroud)

以下是他们提案中的更深入的解释(参见第4页):

有人建议(重新)使用关键字typedef - 如文[4]所述 - 引入模板别名:

template<class T>
typedef std::vector<T,MyAllocator<T>> Vec;
Run Code Online (Sandbox Code Playgroud)

该符号具有使用已知的关键字引入类型别名的优点.但是,它还显示了一些缺点,其中混淆使用已知的关键字在别名未指定类型但模板的上下文中为类型名称引入别名; Vec不是一个类型的别名,不应该采取一个typedef名.该名称Vec是该系列的名称std::vector<*,MyAllocator<*>>- 其中星号是类型名称的占位符.因此,我们不建议使用"typedef"语法.

template<class T>
using Vec = std::vector<T,MyAllocator<T>>;
Run Code Online (Sandbox Code Playgroud)

可以被读/解释为:从现在开始,我将Vect<T>用作同义词std::vector<T,MyAllocator<T>>.通过该读取,用于别名的新语法似乎合理逻辑.

所以他在这里基本上有两点:

  1. 一个using模板变成的类型,而不是一个类型的家庭,所以typedef是"错误的"
  2. using 几乎可以读作英文句子

  • 我在最后一点上同意他的意见......我会说`using`应该来取代typedef.语法不那么模糊. (3认同)

Jos*_*eld 30

你的建议实际上是在2002年由Herb Sutter 在N1406号文件中提出的.例如,它允许写:

template<typename T> typedef X<T,int> Xi; 
Run Code Online (Sandbox Code Playgroud)

后来由Gabriel Dos Reis和Mat Marcus 在N1449进行了修订.他们采用using语法,并注意以下内容:

请注意,我们特别避免使用术语"typedef模板",并引入涉及"using"和"="对的新语法,以帮助避免混淆:我们在这里没有定义任何类型,我们引入了一个同义词(即别名)抽象涉及模板参数的type-id(即类型表达式).

他们还说:

针对语法进行了两次秸秆民意调查.绝大多数人投票避免使用typedef模板语法,而采用"="语法.第二次投票表示强烈偏好"使用"关键字,而不是像"别名"这样的字词,或者在此提案的草稿版本中没有任何关键字.完全使用任何关键字的动机部分源于希望使用可能与上面简要概述的非模板别名方向兼容的语法.

然后在Gabriel Dos Reis和Bjarne Stroustrup 的最终提案N2258中采用了这种语法.

  • 您还可以提到,关于别名模板的语义进行了讨论,N1406/2.2“主要选择:专业化与其他一切”。`using =` 反映了语法级别的语义。 (2认同)