File: overloaded.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 (62 lines) | stat: -rw-r--r-- 2,891 bytes parent folder | download | duplicates (4)
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
59
60
61
62
    Template meta programming comes to the rescue. Knowing that class template
member functions are only instantiated when used, our plan is to design
overloaded tt(add) member functions of which only one is going to be called
(and thus instantiated). Our selection will be based on an additional (in
addition to tt(Type) itself) template non-type parameter that indicates
whether we'll use tt(Storage) for polymorphic or non-polymorphic classes. Our
class tt(Storage) starts like this:
        verb(    template <typename Type, bool isPolymorphic>
    class Storage)

Initially two em(overloaded) versions of our tt(add) member are defined:
one used with tt(Storage) objects storing polymorphic objects (using tt(true)
as its template non-type argument) and one storing value
class objects (using tt(false) as its template non-type argument).

    Unfortunately we run into a small problem: functions cannot be overloaded
by their argument em(values) but only by their argument em(types). But the
small problem may be solved. Realizing that types are defined by the
combination of template names and their template arguments we may convert the
values tt(true) and tt(false) into types using the knowledge from section
ref(INTTYPE) about how to convert integral values to types.

We'll provide one (private) tt(add) member with an tt(IntType<true>) parameter
(implementing the polymorphic class) and another (private) tt(add) member with
an tt(IntType<false>) parameter (implementing the non-polymorphic class).

In addition to these two private members a third (public) member tt(add) is
defined calling the appropriate private tt(add) member by providing an
tt(IntType) argument, constructed from tt(Storage)'s template non-type
parameter.

Here are the implementations of the three tt(add) members:
        verb(    // declared in Storage's private section:

    template <typename Type, bool isPolymorphic>
    void Storage<Type, isPolymorphic>::add(Type const &obj, IntType<true>)
    {
        d_data.push_back(obj.clone());
    }

    template <typename Type, bool isPolymorphic>
    void Storage<Type, isPolymorphic>::add(Type const &obj, IntType<false>)
    {
        d_data.push_back(new Type(obj));
    }

    // declared in Storage's public section:

    template <typename Type, bool isPolymorphic>
    void Storage<Type, isPolymorphic>::add(Type const &obj)
    {
        add(obj, IntType<isPolymorphic>());
    })

The appropriate tt(add) member is instantiated and called because a
primitive value can be converted to a type. Each of the possible template
non-type values is thus used to define an overloaded class template member
function.

    Since class template members are only instantiated when used only one of
the overloaded private tt(add) members is instantiated. Since the other one is
never called (and thus never instantiated) compilation errors are prevented.