"Default Constructors" for built-in types (in templates and elsewhere) - standard?

  • Follow


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)

Similiar Articles:










7/27/2012 6:21:03 PM


Reply: