Why does C++11 not have template typedef?

后端 未结 1 720
无人共我
无人共我 2021-01-19 00:01

Why does C++11 not have \"template typedefs\", like

template typedef std::vector> vec;

Instead

相关标签:
1条回答
  • 2021-01-19 00:51

    n1406 was the proposal by Herb Sutter for "typedef templates" which mimics the syntax in your question. n1499 which proposes "template aliases" supersedes it, which contains the using syntax that's currently present in C++11.

    One of the main drawbacks of the "typedef templates" is addressed in both papers. From 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.

    That "first-class language support" comes in the form of template aliases. We can now look at what n1499 has to say:

    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.

    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.

    0 讨论(0)
提交回复
热议问题