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语法?

我意识到最后一点不能编译,但为什么不能编译?

4

4 回答 4

18

我将仅提及 stroustrup 本人:

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

关键字 using 用于获取线性符号“名称后跟它所指的内容”。我们尝试了传统且复杂的 typedef 解决方案,但在我们确定了一种不太晦涩的语法之前,我们从未设法获得完整且连贯的解决方案。

于 2013-10-17T22:33:52.087 回答
9

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

有人建议(重新)使用typedef论文 [4] 中所做的关键字来引入模板别名:

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

该表示法的优点是使用已知的关键字来引入类型别名。但是,它也显示了几个缺点,其中在别名不指定类型而是模板的上下文中使用已知的关键字为类型名称引入别名会造成混淆;Vec 不是类型的别名,不应作为 typedef-name。名称 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 Proposed Addition to C++: Typedef Templates (by Herb Sutter)。它使用不同的语法(typedefvs using)以及不同的命名法(typedef 模板与模板别名)。Herb 提出的语法没有成功,但有时可以在非正式讨论中找到该命名法。

于 2013-10-18T07:50:47.693 回答
0

One more reason for the new syntax - typedefs for functions, arrays and similar constructs become a bit more comprehensible.

Reference to array before / after:

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

Array of function pointers before / after:

typedef void(*my_type[3])();
using my_type = void(*[3])();
于 2013-10-17T23:35:29.007 回答
0

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


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

[C++11: 7.1.3/2]:typedef-name也可以由alias -declaration引入。关键字后面的标识符using成为typedef-name,标识符后面的可选属性说明符序列属于该typedef-name它具有与由说明符引入的语义相同的语义typedef。特别是,它没有定义新类型,并且不应出现在type-id中。

但是,模板typedef不存在!

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

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

于 2013-10-17T22:32:25.330 回答