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

时间:2014-07-23 16:52:44

标签: c++ templates c++11 typedef using

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

注意:这不是“使用和typedef之间的区别”问题的克隆。我知道using提供了定义typedef系列的优势。我要问的是,为什么标准人员决定使用此using关键字而不是typedef关键字。这似乎只会增加语言的混乱。

2 个答案:

答案 0 :(得分:43)

以下Bjarne Stroustrup说明了为什么他们引入using而不是扩展typedef

  

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

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

  

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

using PF = void (*)(double);

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

typedef void(*PF)(double);

以下是他们提案中的explanation(请参阅第4页),更为深入:

  

有人建议(重新)使用关键字typedef - 就像在。中所做的那样   论文[4] - 介绍模板别名:

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

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

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

可以被读取/解释为:从现在开始,我将Vect<T>用作std::vector<T,MyAllocator<T>> 的同义词。通过该读取,别名的新语法看起来相当合理。

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

  1. using模板成为一系列类型,而不是类型,因此typedef是&#34;错误&#34;
  2. using几乎可以作为英语句子阅读

答案 1 :(得分:30)

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

template<typename T> typedef X<T,int> Xi; 

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

  

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

他们还说:

  

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

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