File: types.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 (80 lines) | stat: -rw-r--r-- 3,608 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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

    tt(Data()) in the last example of the previous section defines a default
constructed anonymous tt(Data) object. This takes us back to the compiler
error. According to the compiler, our original tt(d1) apparently was not of
type tt(Data), but of type tt(Data()). So what's that?

    Let's first have a look at our second constructor. It expects an
tt(int). We would like to define another tt(Data) object, using the second
constructor and want to pass the default tt(int) value to the constructor,
using tt(int()). We know this defines a default tt(int) value, as tt(cout <<
int() << '\n') nicely displays 0, and tt(int x = int()) also initialized x to 
0. So we try tt(`Data di(int())') in tt(main).

    Not good: again the compiler complains when we try to use
tt(di). After tt(`di.display()') the compiler tells us:
    quote(em(error: request for member 'display' in 'di', which is of
non-class type 'Data(int (*)())'))

Oops, again not as expected.... Didn't we pass 0? Why the sudden pointer?
Well, we're once again encountering the compiler's same `use a declaration
when possible' strategy. The notation tt(Type()) not only represents the
default value of type tt(Type), but it's also a shorthand notation for an
anonymous pointer to a function, not expecting arguments, and returning a
tt(Type) value, which you can verify by defining tt(`int (*ip)() = nullptr'),
and passing tt(ip) as argument to tt(di): tt(di(ip)) compiles fine.

So why doesn't the error occur when inserting tt(int()) or assigning tt(int())
to tt(int x)? In these latter cases nothing is declared. Rather, `tt(cout)'
and `tt(int x =)' require expressions resulting in values, which is provided
by tt(int())'s `natural' interpretation. But with tt(`Data di(int())') the
compiler again has a choice, and (by design) it chooses a declaration because
the declaration takes priority. Now tt(int())'s interpretation as an anonymous
pointer is available and therefore used.

Likewise, if tt(int x) has been defined, tt(`Data b1(int(x))') declares tt(b1)
as a function, expecting an tt(int) (as tt(int(x)) represents a type), while
tt(`Data b2((int)x)') defines tt(b2) as a tt(Data) object, using the
constructor expecting a single tt(int) value.

Again, to use default entities, values or objects, prefer tt({}) over tt(()):
tt(Data di{ int{} }) defines tt(di) of type tt(Data), calling the tt(Data(int
x)) constructor and uses tt(int's) default value 0.
        
But what about the compiler's original complaint? The compiler told us that
our original tt(d1) was not of type tt(Data), but of type tt(Data()). But
what's that? The parentheses in the error message are important: it indicates
a function: tt(d1), because of the subsequent parentheses, declares a
function, not expecting arguments, and returning a tt(Data) object. Shorthand:
tt(Data()), more verbosely: tt(Data (*)()). As a final illustration: the
following program writes tt(hello world) twice, and tt(Data d1()) in tt(main)
simply is an explicit local declaration of the globally defined function
tt(d1), further illustrated by the assignment of tt(d1) to the explicitly
declared pointer to a function tt(pf), returning a tt(Data) object:
    verb(    #include <iostream>
    #include "data.h"
    
    Data::Data()
    {}

    Data d1()
    {
        std::cout << "hello world\n";
        return Data{};
    }
    
    int main()
    {
        Data d1();
    
        d1();
        Data (*pf)() = d1;
    
        pf();   // or (same): (*pf)()
    })
    Also, as tt(d1()) returns a tt(Data) object, a statement like
tt(d1().display()) correctly compiles.