在C ++ 11中,您可以创建一个"类型别名"通过做像
这样的事情template <typename T>
using stringpair = std::pair<std::string, T>;
但这偏离了您期望的模板typedef看起来像:
template <typename T>
typedef std::pair<std::string, T> stringpair;
所以这提出了一个问题 - 为什么他们需要提出一个新的语法?什么是旧的typedef
语法无效?
我意识到最后一点没有编译,但为什么不能编译?
答案 0 :(得分:18)
我只想提到stroustrup自己:
http://www.stroustrup.com/C++11FAQ.html#template-alias
关键字using用于获取线性表示法“名称后跟 它指的是什么。“我们尝试了传统的和复杂的 typedef解决方案,但从未设法获得完整和连贯的解决方案 解决方案,直到我们找到一个不那么模糊的语法。
答案 1 :(得分:9)
来自WG21提案N1489 Template aliases(由Stroustrup和Dos Reis撰写):
有人建议(重新)使用关键字
typedef
论文[4]介绍模板别名:template<class T> typedef std::vector<T, MyAllocator<T> > Vec;
该符号具有使用已知关键字的优势 引入一个类型别名。但是,它也显示出一些不利之处 其中混淆使用已知的关键字引入 别名未指定的上下文中的类型名称的别名 一个类型,但一个模板; Vec不是类型的别名,不应该 被用于typedef名称。 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(由Herb Sutter提出)。它使用不同的语法(typedef
vs using
)以及不同的命名法(typedef templates vs template aliases)。赫伯提出的语法没有成功,但有时可以在非正式讨论中找到命名法。
答案 2 :(得分:0)
(tl; dr:using
支持模板,而typedef
则不支持。)
听起来你已经知道了,两个例子没有模板之间的区别是什么:
[C++11: 7.1.3/2]:
alde-name 也可以通过 alias-declaration 引入。using
关键字后面的标识符变为 typedef-name ,并且可选的 attribute-specifier-seq 跟随 typedef-name <的标识符/ em>的。 它具有与typedef
说明符引入的语义相同的语义。特别是,它没有定义新类型,它不会出现在 type-id 中。
但是,模板typedef
不存在!
[C++11: 14.5.7/1]:
模板声明,其中声明是 alias-declaration (第7条),将标识符声明为别名模板。别名模板是一系列类型的名称。别名模板的名称是模板名称。
为什么他们不重复使用typedef
语法?好吧,我认为typedef
只是“旧”风格,并且考虑到在其他环境中使用using
,我们决定新功能应采用using
形式以保持一致。 / p>
答案 3 :(得分:0)
新语法的另一个原因 - 函数,数组和类似结构的typedef变得更容易理解。
在之前/之后引用数组:
typedef int(&my_type)[3];
using my_type = int(&)[3];
之前/之后的函数指针数组:
typedef void(*my_type[3])();
using my_type = void(*[3])();