模板typedef的新“使用”语法解决了什么问题?

时间:2013-10-17 22:26:36

标签: c++ templates c++11 typedef template-aliases

在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 个答案:

答案 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])();