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
|
tt(Data()), which in the above context defines a default constructed
anonymous tt(Data) object, 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, but 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 define 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:
em(error: request for member 'display' in 'di', which is of non-class type
'Data(int (*)())')
Oops, not as expected.... Didn't we pass 0? Why the sudden pointer? It's that
same `use a declaration when possible' strategy again. 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 =) need expressions determining 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.
|