7

I always thought that implicit constructor in C++ could only be a constructor with only one argument. For example:

class Foo1
{
   Foo(int); // This could be an implicit constructor
};

But is the following code right:

class Foo2
{
    Foo2(int, int=0);  // Would compiler use this as an implicit constructor?
}

I can do this:

Foo1 obj;
...
obj = 5;

What about Foo2?

7
  • Explicit constructor has a different meaning. What you are talking is about constructor with default arguments. Commented Feb 16, 2012 at 2:24
  • @mahesh I know the meaning of explicit constructors and question is a question :) Okay, I will fill it with an example. Commented Feb 16, 2012 at 2:25
  • 5
    None of those are explicit constructors--they're not marked with explicit keyword. Do you mean implicit constructor? If so, yes, constructors can be invoked implicitly if the n+1 parameters are assigned default arguments. Commented Feb 16, 2012 at 2:29
  • How is obj = 5; is a valid statement ? Am I missing anything here ? Commented Feb 16, 2012 at 2:30
  • @cody-gray Yep, thanks. I've already changed that. You can post your comment as an answer. Commented Feb 16, 2012 at 2:31

4 Answers 4

7

First, any constructor can be marked explicit. How many arguments it has is irrelevant.

With that out of the way, you just now need to understand what explicit really means. It just means that the only way that constructor can be called is when you explicitly specify the class name:

struct foo
{
    foo(int){}
    explicit foo(double){}
};

void bar(foo){}

bar(5); // okay, calls foo(int) to construct the foo
bar(3.14); // error, cannot call foo(double) because foo was not explicitly used
bar(foo(3.14)); // okay, calls foo(double) to construct the foo

The reason we don't mark multiple-argument constructors explicit is because it's useless. Given:

struct baz
{
    baz(int, int, int);
};

How else can you call that constructor other than saying baz anyway? (As in baz(1, 2, 3).)†

In your example, explicit would be sensible because you could call that constructor with only one argument. What you actually do only depends on if you feel it should be implicitly convertible or not.


†This is disregarding C++11 initializer lists. In C++11, I think you could say:

void qaz(baz) {}

qaz({1, 2, 3}); 

And manage to get an implicit conversion to a multiple-argument constructor, but I don't know enough about initializer-lists to make a meaningful comment except as a footnote.

Sign up to request clarification or add additional context in comments.

3 Comments

I always mark all constructors explicit, for two reasons: symmetry, and the chance that someday some programmer might decide that all but the first argument could use some default value, and add it. (Except for ctors that I really want to do implicit conversions of course, which I almost never do)
@PaulGroke: Making all constructors explicit is not needed. Only those which take one argument, is what I think need to be marked explicit.
@Nawaz: I know that it's not needed, and quite frankly I'm not sure how you could ever misinterpret my comment to come to the conclusion that I wouldn't.
2

If I understand what you're asking, then the answer is yes.

To be more specific, essentially any ctor that can be invoked with only one argument can and will be used for implicit conversions. To prevent that, such a ctor can be marked explicit. That applies equally to a ctor that only takes one argument, or one that can take more than one argument, but supplies default values for the other arguments.

Comments

1

You're confusing EXplicit and IMplicit here. What you're talking about are conversion constructors. An explicit constructor is just the opposite: one that can not be used for (implicit) conversions.

And to answer your question: yes, Foo2(int, int=0) is a conversion constructor that enables implicit conversion like in obj = 5, becaust it can be called with one int argument.

The same goes for default constructors: if you add a default value for the first parameter as well, it will additionally become the default constructor.

Comments

1

What you probably meant is implicit constructors, not explicit.

Anyway, you cannot do this (as opposed to what you think you can):

Foo1 obj; //this line will not compile as it takes one argument!
obj = 5;

I'm sure you've not compiled your code before saying you can do this.

However, if you meant this,

Foo1 obj(10); //OK now
obj = 5;

Then yes, you can.

Now how about Foo2? Well, you can do so in case of Foo2 as well:

Foo2 foo(10);
foo = 5;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.