c++ - 为什么 C++11 没有模板类型定义?

标签 c++ c++11 language-lawyer

为什么 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 rewrite foo 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/

相关文章:

c++ - 加倍到 Const Char*

c++ - 如何使用 CUDA 实现 2-for 粒子交互循环,由此产生的复杂性是什么?

c++ - 为 std::bind 创建模板包装器

c++ - 无法将参数 2 从 'std::string *' 转换为 'std::string'

c++ - 跨编译器的诊断不一致,以缩小非类型模板参数中的转换范围

c++ - 是否假定C/C++中的所有函数都返回?

c++ - C++11 中的静态局部变量?

c++ - 用 vector 构建动态递归结构

c++ - 如何使用自定义分配器创建 std::function?

c++ - 构造函数干扰成员变量指定初始化器?