简体   繁体   English

为什么C ++ 11没有模板typedef?

[英]Why does C++11 not have template typedef?

Why does C++11 not have "template typedefs", like 为什么C ++ 11没有“模板类型定义”,比如

template<typename T> typedef std::vector<T, myalloc<T>> vec;

Instead they only allow the new syntax: 相反,他们只允许新语法:

template<typename T> using vec = std::vector<T, myalloc<T>>;

n1406 was the proposal by Herb Sutter for "typedef templates" which mimics the syntax in your question. n1406是Herb Sutter关于“typedef templates”的提议,它模仿了你问题中的语法。 n1499 which proposes "template aliases" supersedes it, which contains the using syntax that's currently present in C++11. 建议使用“模板别名”的n1499取代它,它包含当前存在于C ++ 11中的using语法。

One of the main drawbacks of the "typedef templates" is addressed in both papers. 两种论文都提到了“typedef模板”的一个主要缺点。 From n1406: 从n1406:

In existing practice, including in the standard library, type names nested inside helper class templates are used to work around this problem in many cases. 在现有实践中,包括在标准库中,嵌套在辅助类模板中的类型名称在很多情况下用于解决此问题。 The following is one example of this usual workaround; 以下是这种常用解决方法的一个例子; the main drawback is the need to write ::Type when using the typedef'd name. 主要缺点是在使用typedef'd名称时需要编写:: Type。

 template< typename T > struct SharedPtr { typedef Loki::SmartPtr < T, // note, T still varies RefCounted, // but everything else is fixed NoChecking, false, PointsToOneObject, SingleThreaded, SimplePointer<T> // note, T can be used as here > Type; }; SharedPtr<int>::Type p; // sample usage, “::Type” is ugly 

What we'd really like to be able to do is simply this: 我们真正希望能做的就是:

 template< typename T > typedef Loki::SmartPtr < T, // note, T still varies RefCounted, // but everything else is fixed NoChecking, false, PointsToOneObject, SingleThreaded, SimplePointer<T> // note, T can be used as here > SharedPtr; SharedPtr<int> p; // sample usage, “::Type” is ugly 

[...] [...]

The workaround is ugly, and it would be good to replace it with first-class language support that offers users a natural C++ template syntax. 解决方法很难看,最好用一流的语言支持替换它,为用户提供自然的C ++模板语法。

That "first-class language support" comes in the form of template aliases. “一流的语言支持”以模板别名的形式出现。 We can now look at what n1499 has to say: 我们现在可以看一下n1499的内容:

In this paper we will focus on describing an aliasing mechanism that allows the two semantics mentioned in N1406 to coexist instead being regarded as mutually exclusive. 在本文中,我们将集中描述一种别名机制,该机制允许N1406中提到的两个语义共存,而不是被视为互斥。 First let's consider a toy example: 首先让我们考虑一个玩具示例:

 template <typename T> class MyAlloc {/*...*/}; template <typename T, class A> class MyVector {/*...*/}; template <typename T> struct Vec { typedef MyVector<T, MyAlloc<T> > type; }; Vec<int>::type p; // sample usage 

The fundamental problem with this idiom, and the main motivating fact for this proposal, is that the idiom causes the template parameters to appear in non-deducible context. 这个习语的根本问题,以及这个提议的主要动机是,这个习惯用法使模板参数出现在不可导出的上下文中。 That is, it will not be possible to call the function foo below without explicitly specifying template arguments. 也就是说,如果没有明确指定模板参数,就不可能在下面调用函数foo

 template <typename T> void foo (Vec<T>::type&); 

Also, the syntax is somewhat ugly. 此外,语法有点难看。 We would rather avoid the nested ::type call. 我们宁愿避免嵌套的:: type调用。 We'd prefer something like the following: 我们更喜欢以下内容:

 template <typename T> using Vec = MyVector<T, MyAlloc<T> >; //defined in section 2 below Vec<int> p; // sample usage 

Note that we specifically avoid the term "typedef template" and introduce the new syntax involving the pair "using" and "=" to help avoid confusion: we are not defining any types here, we are introducing a synonym (ie alias) for an abstraction of a type-id (ie type expression) involving template parameters. 请注意,我们特别避免使用术语“typedef模板”,并引入涉及“using”和“=”对的新语法,以帮助避免混淆:我们在这里没有定义任何类型,我们引入了一个同义词(即别名)抽象涉及模板参数的type-id (即类型表达式)。 If the template parameters are used in deducible contexts in the type expression then whenever the template alias is used to form a template-id , the values of the corresponding template parameters can be deduced – more on this will follow. 如果模板参数在类型表达式中的可推导上下文中使用,那么每当使用模板别名来形成模板ID时 ,可以推导出相应模板参数的值-接下来将对此进行更多介绍。 In any case, it is now possible to write generic functions which operate on Vec<T> in deducible context, and the syntax is improved as well. 在任何情况下,现在可以编写在可推导上下文中对Vec<T>进行操作的泛型函数,并且语法也得到改进。 For example we could rewrite foo as: 例如,我们可以将foo重写为:

 template <typename T> void foo (Vec<T>&); 

We underscore here that one of the primary reasons for proposing template aliases was so that argument deduction and the call to foo(p) will succeed. 我们在此强调,提出模板别名的主要原因之一是参数推断和对foo(p)的调用将成功。

So you can see that n1499 addresses the problems in n1406 as well as introducing a syntax that's much cleaner and easier to read. 因此,您可以看到n1499解决了n1406中的问题,并引入了更清晰,更易于阅读的语法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM