explicit default constructor

M

Marcelo Pinto

Hi all,

In practice, what is the diference between a default constructor and
an explicit default constructor?

class Ai
{
public:
Ai() {}
};

class Ae
{
public:
explicit Ai() {}
};

Another question. I read in another thread that, if you provide
explicitly one constructor, the implementation shall not implicitly
declare/define the default constructor and the copy constructor
(12.1), but I couldn't find where the standard stated this rule. Is it
really true? Where is it stated?

Thanks,

Marcelo Pinto.
 
V

Victor Bazarov

Marcelo said:
In practice, what is the diference between a default constructor and
an explicit default constructor?

None, IIUIC.
class Ai
{
public:
Ai() {}
};

class Ae
{
public:
explicit Ai() {}

explicit Ae() {}
};

Another question. I read in another thread that, if you provide
explicitly one constructor, the implementation shall not implicitly
declare/define the default constructor and the copy constructor
(12.1), but I couldn't find where the standard stated this rule. Is it
really true? Where is it stated?

No, it's not really true. At least it's not completely true. If you
declare a parameterized c-tor, there will be no default c-tor declared
implicitly. The implicit copy c-tor is still going to be provided.

See Standard, 12.1/5 "If there is no user-declared constructor for
class X, a default constructor is implicitly declared."

Victor
 
K

Karl Heinz Buchegger

Marcelo said:
Hi all,

In practice, what is the diference between a default constructor and
an explicit default constructor?

class Ai
{
public:
Ai() {}
};

class Ae
{
public:
explicit Ai() {}
};

If you mark a constructor as explicit, then the compiler cannot
use that constructor under the hood to adjust types. At the moment
I cannot think of a case where one wants to do this with a default
constructor that takes no arguments.
But

class A
{
public:
A( int i_ = 0 ) : i( i_ ) {}
protected:
int i;
};

void foo( A Arg )
{
}

int main()
{
foo( 5 );
}

Here the compiler uses the constructor to create an A object which
can be used to call foo. If you mark the constructor as explicit,
then this is no longer allowed. You would need to write

int main()
{
foo( A(5) );
}

and thus create the A object explicitely.

Another question. I read in another thread that, if you provide
explicitly one constructor, the implementation shall not implicitly
declare/define the default constructor and the copy constructor
(12.1), but I couldn't find where the standard stated this rule. Is it
really true?

No.

If you don't declare any constructor, the compiler will declare
a default constructor.
If you don't declare a copy constructor, the compiler will declare
a copy constructor too.

So:
any constructor declared (with the exception of the copy constructor)
-> the compiler will not declare a default constructor

you declare a copy constructor -> the compiler will no longer declare
a copy constructor for you.
Where is it stated?

Section 12 and 12.1 is fine
 
J

John Harrison

Marcelo Pinto said:
Hi all,

In practice, what is the diference between a default constructor and
an explicit default constructor?

class Ai
{
public:
Ai() {}
};

class Ae
{
public:
explicit Ai() {}
};

I don't think the second is legal. Explicit is for constructors that can be
called with one argument and it prevents that constructor from being used to
implicitly convert the type of the argument to the type of the class.

struct A
{
A();
A(int);
};

struct B
{
B();
explicit B(int);
};

A a;
B b;

a = 2; // legal
b = 2; // illegal constructor is explicit
b = B(2); // legal, constructor is used explicitly
Another question. I read in another thread that, if you provide
explicitly one constructor, the implementation shall not implicitly
declare/define the default constructor and the copy constructor
(12.1), but I couldn't find where the standard stated this rule. Is it
really true? Where is it stated?

Its true for the default constructor, it is not true for the copy
constructor. This have nothing to do with the explicit keyword that you
mentioned above.

john
 
S

Sharad Kala

John Harrison said:
I don't think the second is legal. Explicit is for constructors that can
be

I do agree that it doesn't make much sense to declare explicit here. But
what makes you say that the code is illegal ? VC 7.1, g++ 3.1 and Comeau
online don't seem to think it as illegal. Could you please quote the
standard.

-Sharad
 
V

Victor Bazarov

Sharad said:
be

I do agree that it doesn't make much sense to declare explicit here. But
what makes you say that the code is illegal ? VC 7.1, g++ 3.1 and Comeau
online don't seem to think it as illegal. Could you please quote the
standard.

John is incorrect. The Standard explicitly _allows_ the default
c-tor to be declared 'explicit' (no pun intended). See 12.3.1/2

Victor
 
J

John Harrison

be

I do agree that it doesn't make much sense to declare explicit here. But
what makes you say that the code is illegal ? VC 7.1, g++ 3.1 and Comeau
online don't seem to think it as illegal. Could you please quote the
standard.

I did say 'I don't *think* its legal'. I wasn't sure on the point and I
didn't think it was particularly important so I didn't look it up. I'm quite
happy to accept that the code is in fact legal (though senseless as you
say).

The main issue with the OP's post was that he seemed to have got mixed up
between explicitly defined constructors (as opposed to implicit compiler
generated constructors) and the explicit keyword when used on a constructor
and that was the point I tried to address in my reply.

john
 
R

Rolf Magnus

Victor said:
John is incorrect. The Standard explicitly _allows_ the default
c-tor to be declared 'explicit' (no pun intended). See 12.3.1/2

I wonder why the standard explicitly (also no pun intended) states that
"such a constructor will be used to perform default-initialization". I
mean, that's what default constructors generally do, not just when
declared 'explicit'.
 
R

Rob Williscroft

Rolf Magnus wrote in in
comp.lang.c++:
I wonder why the standard explicitly (also no pun intended) states that
"such a constructor will be used to perform default-initialization". I
mean, that's what default constructors generally do, not just when
declared 'explicit'.

Presumably its pointing out that it has no effect i.e you can still do:

explicit_default_type value;

And don't have to do:

explicit_default_type value = explicit_default_type();

Rob.
 
M

Marcelo Pinto

John Harrison said:
I did say 'I don't *think* its legal'. I wasn't sure on the point and I
didn't think it was particularly important so I didn't look it up. I'm quite
happy to accept that the code is in fact legal (though senseless as you
say).

The main issue with the OP's post was that he seemed to have got mixed up
between explicitly defined constructors (as opposed to implicit compiler
generated constructors) and the explicit keyword when used on a constructor
and that was the point I tried to address in my reply.

I wasn't mixing the two :). I tried to find an explanation of the
consequences of using the keyword _explicit_ with a default
constructor and the threads I found talked about the implicit
declaration/definition of constructors and I could not find the
circunstances in which this wasn't allowed to happen (reading the
standard), so I asked the other question.

Thanks.

Marcelo Pinto
 
M

Marcelo Pinto

Victor Bazarov said:
None, IIUIC. Sorry, what is IIUIC?


explicit Ae() {}

I always make these silly mistakes :(
No, it's not really true. At least it's not completely true. If you
declare a parameterized c-tor, there will be no default c-tor declared
implicitly. The implicit copy c-tor is still going to be provided.

See Standard, 12.1/5 "If there is no user-declared constructor for
class X, a default constructor is implicitly declared."

Thank you. I read it more than once and always read it as if it stated
"If there is no user-declared *default* constructor for class X, a
default constructor is implicitly declared." Thats why I couldn't see
:(

Thank you very much.

Marcelo Pinto
 
A

Andrey Tarasevich

Rolf said:
...

I wonder why the standard explicitly (also no pun intended) states that
"such a constructor will be used to perform default-initialization". I
mean, that's what default constructors generally do, not just when
declared 'explicit'.
...

One thing that should be taken into account here is that default
constructor is not necessarily a constructor without parameters. Default
constructor is a constructor that can be invoked without specifying any
arguments. It can have any number of parameters, as long as all of them
have default arguments. This means that a constructor can be both
default constructor and conversion constructor at the same time.
Applying the keyword 'explicit' to such dual-role constructor makes
perfect sense.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,479
Latest member
JaysonK723

Latest Threads

Top