Topic: Q about Inheriting Constructors


Author: Scott Meyers <usenet@aristeia.com>
Date: Tue, 19 May 2009 12:00:36 CST
Raw View
In N2800, 12.9/6 reads, in part:

struct B1 {
 B1(int);
};

struct D1 : B1 {
 using B1::B1;
};

The set of constructors present in D1 is
    D1(), implicitly-declared default constructor, ill-formed if used

So D1 has a default constructor.  But a short while later (in 12.9/9),
we see this:

struct B1 {
 B1(int) { }
};

struct D1 : B1 {
 using B1::B1; // implicitly declares D1(int)
 int x;
};

void test() {
 D1 d(6);   // OK: d.x is not initialized
 D1 e;      // error: D1 has no default constructor
}

Now D1 has no default constructor.  I realize that the net effect is
the same (the code does not compile), but I'm not sure whether I'm
overlooking a subtle difference in semantics in these examples or
whether the terminology simply changed from "present but ill-formed if
used" to "not present."  Can someone clarify?

Thanks,

Scott


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: daniel.kruegler@googlemail.com
Date: Tue, 19 May 2009 21:49:24 CST
Raw View
On 19 Mai, 20:00, Scott Meyers <use...@aristeia.com> wrote:
> In N2800, 12.9/6 reads, in part:
>
> struct B1 {
>  B1(int);
>
> };
>
> struct D1 : B1 {
>  using B1::B1;
>
> };
>
> The set of constructors present in D1 is
>     D1(), implicitly-declared default constructor, ill-formed if used
>
> So D1 has a default constructor.  But a short while later (in 12.9/9),
> we see this:
>
> struct B1 {
>  B1(int) { }
>
> };
>
> struct D1 : B1 {
>  using B1::B1; // implicitly declares D1(int)
>  int x;
>
> };
>
> void test() {
>  D1 d(6);   // OK: d.x is not initialized
>  D1 e;      // error: D1 has no default constructor
>
> }
>
> Now D1 has no default constructor.  I realize that the net effect is
> the same (the code does not compile), but I'm not sure whether I'm
> overlooking a subtle difference in semantics in these examples or
> whether the terminology simply changed from "present but ill-formed if
> used" to "not present."  Can someone clarify?

The reason for this seemingly redundant description is due
to the fact that according to [class.ctor]/5

"[..] If there is no user-declared constructor for class X, a
constructor
having no parameters is implicitly declared.[..]"

a class without any user-declared constructor has an implicitly
declared default constructor. *But* a using-declaration naming
a constructor is *not* a user-declared constructor ;-)

This becomes evident by reading 12.9 [class.inhctor]/3:

"For each non-template constructor in the candidate set of
inherited constructors other than a constructor having no
parameters or a copy constructor having a single parameter,
a constructor is implicitly declared with the same constructor
characteristics unless there is a user-declared constructor
with the same signature in the class where the using-
declaration appears.[..]"

In the example you quoted there is no user-declared
constructor in D1, therefore the implicitly-declared
"default-constructor" is not suppressed, see also p.5:

"5 [ Note: Default and copy constructors may be implicitly
declared as specified in 12.1 and 12.8.    end note ]"

So why says the wording "ill-formed if used"? The reason
is an implication based on the standard rules for
default constructors carved in stone in [class.ctor]/6:

"A non-user-provided default constructor for a class is
implicitly defined when it is used (3.2) to create an object
of its class type (1.8).[..] If that user-written default
constructor would be ill-formed, the program is ill-formed.
[..] Before the non-user-provided default constructor for a
class is implicitly defined, all the non-user-provided default
constructors for its base classes and its nonstatic data
members shall have been implicitly defined.[..]"

Exactly the last two conditions are not satisfied, because
the base class B1 does not have an implicitly (or explicitly)
defined default constructor.

Greetings from Bremen,

Daniel Kr   gler


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Scott Meyers <usenet@aristeia.com>
Date: Wed, 20 May 2009 23:53:18 CST
Raw View
daniel.kruegler@googlemail.com wrote:
> On 19 Mai, 20:00, Scott Meyers <use...@aristeia.com> wrote:
>> In N2800, 12.9/6 reads, in part:
>>
>> struct B1 {
>>  B1(int);
>>
>> };
>>
>> struct D1 : B1 {
>>  using B1::B1;
>>
>> };
>>
>> The set of constructors present in D1 is
>>    D1(), implicitly-declared default constructor, ill-formed if used
>>
>> So D1 has a default constructor.  But a short while later (in 12.9/9),
>> we see this:
>>
>> struct B1 {
>>  B1(int) { }
>>
>> };
>>
>> struct D1 : B1 {
>>  using B1::B1; // implicitly declares D1(int)
>>  int x;
>>
>> };
>>
>> void test() {
>>  D1 d(6);   // OK: d.x is not initialized
>>  D1 e;      // error: D1 has no default constructor
>>
>> }
>>
>> Now D1 has no default constructor.  I realize that the net effect is
>> the same (the code does not compile), but I'm not sure whether I'm
>> overlooking a subtle difference in semantics in these examples or
>> whether the terminology simply changed from "present but ill-formed if
>> used" to "not present."  Can someone clarify?
>
> The reason for this seemingly redundant description is due
> to the fact that according to [class.ctor]/5
>
> "[..] If there is no user-declared constructor for class X, a
> constructor
> having no parameters is implicitly declared.[..]"

So "present in D1" means *declared* in D1.  Clearly, the implicit
declaration of
a default constructor in D1 is not itself problematic.

> So why says the wording "ill-formed if used"? The reason
> is an implication based on the standard rules for
> default constructors carved in stone in [class.ctor]/6:
>
> "A non-user-provided default constructor for a class is
> implicitly defined when it is used (3.2) to create an object
> of its class type (1.8).[..] If that user-written default
> constructor would be ill-formed, the program is ill-formed.
> [..] Before the non-user-provided default constructor for a
> class is implicitly defined, all the non-user-provided default
> constructors for its base classes and its nonstatic data
> members shall have been implicitly defined.[..]"
>
> Exactly the last two conditions are not satisfied, because
> the base class B1 does not have an implicitly (or explicitly)
> defined default constructor.

So "D1 has no default constructor" means that D1 has declared a default
constructor, but an implicitly-generated definition would need to call a
default
constructor in the base class, and there is no such constructor to call.

I think things would be clearer if the comment about D1 having no default
constructor were changed to something like "error:  use of default
constructor
is ill-formed".

Thanks for your explanation.  Thanks also to you and others for the other
explanations you have provided in the other threads I have posted.  I'm
sure
there will be additional questions about C++0x, so I'll thank you all in
advance
for the help I hope will continue to be forthcoming.

Scott


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]