为什么 C++11 没有“模板类型定义”,比如
template<typename T> typedef std::vector<T, myalloc<T>> vec;
相反,他们只允许新语法:
template<typename T> using vec = std::vector<T, myalloc<T>>;
最佳答案
n1406是 Herb Sutter 提出的“typedef 模板”的提议,它模仿了您问题中的语法。 n1499建议“模板别名”取代它,其中包含 using
当前存在于 C++11 中的语法。
“typedef 模板”的主要缺点之一在这两篇论文中都得到了解决。来自 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.
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.
“一流的语言支持”以模板别名的形式出现。我们现在可以看看 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. 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.template <typename T> void foo (Vec<T>::type&);
Also, the syntax is somewhat ugly. We would rather avoid the nested ::type call. 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 (i.e. alias) for an abstraction of a type-id (i.e. type expression) involving template parameters. 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. 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. For example we could rewritefoo
as: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.
因此您可以看到 n1499 解决了 n1406 中的问题,并引入了一种更清晰、更易于阅读的语法。
关于c++ - 为什么 C++11 没有模板类型定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27458662/