In a template that varies on typename T, I sometimes want a function
parameter that has a default of T():
template <typename T> void foo(const T& t = T()) {...}
If T ends up as a class, then the class is expected to have a default
constructor, and all goes as expected.
But when T is a built-in type, the compiler I use is apparently being
very helpful and coming up with a conveniently "zero" or "false"
default value for T(). pointers types like char* come up NULL, ints
and floats are 0, bools are false. This is absolutely ideal for me,
but I can't figure out if it's guaranteed behaviour, and my code needs
to be portable.
And since I remember from my C days that a NULL pointer doesn't have
to be represented internally by an all-bit-zero quantity (though I've
never worked on a system where it wasn't), I'm wondering if T() where
T=char* is really going to be guaranteed NULL.
Experimenting in a specific compiler, I've verified that int a =
int(); sets a to zero. But char* a = char*(); doesn't compile. (I was
vaguely surprised that either compiled). This makes me nervous; it
implies that T() in a template is doing something "special" when T=X*.
Can someone confirm that basic types and pointer types have a sort of
default "constructor" that provides the generic "false" value, in (at
least) templates?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
ScottM
|
3/18/2011 5:50:07 PM |
|
Am 19.03.2011 00:50, schrieb ScottM:
>
> In a template that varies on typename T, I sometimes want a function
> parameter that has a default of T():
>
> template<typename T> void foo(const T& t = T()) {...}
>
> If T ends up as a class, then the class is expected to have a default
> constructor, and all goes as expected.
>
> But when T is a built-in type, the compiler I use is apparently being
> very helpful and coming up with a conveniently "zero" or "false"
> default value for T(). pointers types like char* come up NULL, ints
> and floats are 0, bools are false. This is absolutely ideal for me,
> but I can't figure out if it's guaranteed behaviour, and my code needs
> to be portable.
>
> And since I remember from my C days that a NULL pointer doesn't have
> to be represented internally by an all-bit-zero quantity (though I've
> never worked on a system where it wasn't), I'm wondering if T() where
> T=char* is really going to be guaranteed NULL.
>
> Experimenting in a specific compiler, I've verified that int a =
> int(); sets a to zero. But char* a = char*(); doesn't compile. (I was
> vaguely surprised that either compiled). This makes me nervous; it
> implies that T() in a template is doing something "special" when T=X*.
>
> Can someone confirm that basic types and pointer types have a sort of
> default "constructor" that provides the generic "false" value, in (at
> least) templates?
It is guaranteed, in templates or outside of them. The base for this is [expr.type.conv] p. 2:
"The expression T(), where T is a simple-type-specifier (7.1.5.2) for a non-array complete object type or the (possibly cv-qualified) void type, creates an rvalue of the specified type, which is value-initialized (8.5; no initialization is done for the void() case)."
[dcl.init] again explains the meaning of value-initialization. For scalar types we end up in zero-initialization, defined to be:
"� if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;"
As far as I know the last statement has always be understood to imply for pointer types the equivalent form of initialization with a null pointer constant as defined in [conv.ptr]:
"A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of pointer to object or pointer to function type."
Nevertheless the current C++0x standard has clarified this a bit by changing [dcl.init] to
"� if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression,
converted to T;103"
where footnote 103 explains:
"As specified in 4.10, converting an integral constant expression whose value is 0 to a pointer type results in a null pointer value."
which should be crystal-clear now.
HTH & Greetings from Bremen,
Daniel Kr�gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
windows
|
3/18/2011 9:37:39 PM
|
|
On Mar 18, 4:50 pm, ScottM <scott.a.m...@gmail.com> wrote:
> But when T is a built-in type, the compiler I use is apparently being
> very helpful and coming up with a conveniently "zero" or "false"
> default value for T(). pointers types like char* come up NULL, ints
> and floats are 0, bools are false. This is absolutely ideal for me,
> but I can't figure out if it's guaranteed behaviour, and my code needs
> to be portable.
It's standard.
Bob
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Bob
|
3/18/2011 9:38:43 PM
|
|
|
2 Replies
263 Views
(page loaded in 0.002 seconds)
|