File: aliases.yo

package info (click to toggle)
c%2B%2B-annotations 13.02.02-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,576 kB
  • sloc: cpp: 25,297; makefile: 1,523; ansic: 165; sh: 126; perl: 90; fortran: 27
file content (58 lines) | stat: -rw-r--r-- 2,884 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
In addition to function and class templates, bf(C++) also uses templates to
define an alias for a set of types. This is called an
    emi(alias template). Alias templates can be specialized. The name of an
alias template is a type name.

Alias templates can be used as arguments to template template parameters. This
allows us to avoid the `unexpected default parameters' you may encounter
(e.g., when using bf(C++) standards before the tt(c++23) standard) when using
template template parameters.  Defining a template specifying a tt(template
<typename> class Container) is fine, but (before tt(c++23)) it was impossible
to specify a container like tt(vector) or tt(set) as template template
argument, as tt(vector) and tt(set) containers also define second template
parameters, specifying their allocation policies.

Alias templates are defined like tt(using) declarations, specifying an alias
for an existing (maybe partially or fully specialized) template type. In the
following example tt(Vector) is defined as an alias for tt(vector):
        verb(    template <typename Type>
    using Vector = std::vector<Type>;

    Vector<int> vi;             // same as std::vector<int>
    std::vector<int> vi2(vi);   // copy construction: OK)

So, what's the point of doing this?
    Looking at the tt(vector) container, we see that it defines two, rather
than one, template parameters, the second parameter being the allocation
policy tt(_Alloc), by default set to tt(std::allocator<_Tp>):
        verb(    template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
    class vector: ...)

Now define a class template tt(Generic) defining a template template
parameter:
        verb(    template <typename Type, template <typename> class Container>
    class Generic: public Container<Type>
    {
        ...
    };)

Most likely, tt(Generic) offers members made available by the container
that is actually used to create the tt(Generic) object, and adds to those some
members of it own. However, a simple container like tt(std::vector) cannot be
used, as tt(std::vector) doesn't match a tt(template <typename> class
Container>) parameter; it requires a tt(template <typename, typename> class
Container>) template template parameter.

    The tt(Vector) alias template, however, em(is) defined as a template
having one template type parameter, and it uses the vector's default
allocator. Consequently, passing a tt(Vector) to tt(Generic) works fine:
        verb(    Generic<int, Vector> giv;       // OK
    Generic<int, std::vector> err;  // won't compile: 2nd argument mismatch)

With the aid of a small alias template it is also possible to use a
completely different kind of container, like a tt(map), with tt(Generic):
        verb(    template <typename Type>
    using MapString = std::map<Type, std::string>;

    Generic<int, MapString> gim;    // uses map<int, string>)