When to make constructor explicit in C++ [closed]
Asked Answered
O

1

48

After reading the following blog :

http://xania.org/200711/ambiguous-overloading

I started asking myself "should I not always explicit define my constructors?"

So I started reading more than found out this article :

http://www.sjbrown.co.uk/2004/05/01/always-use-explicit/

Which shows another example, and also explains his thoughts behind it. But of course this is one blogger's thoughts.

I would be happy to hear from some of you,what your thought on the manner, what is your experience with the subject and a few example for either way would be nice.

Osithe answered 15/9, 2012 at 12:9 Comment(3)
This question is not constructive, because it solicits an opinion. You should change it to ask for "hard facts" instead, for example "what, if any, are the disadvantages of using constructors that the compiler makes automatically", or "What are the rules to decide when I need to define my constructors explicitly"?Gymnast
while I agree with dasblinkenlight, I'd say, yes, always use explicit. it makes it harder to use your class in (accidently) a wrong way and that is a good thingStove
The question asked by oopsi is very useful and I really cant understand why some people are so eager to close the informative question. I strongly think Stackoverflow committee needs to review their policies and make sure the valuable questions are not closed down just because some people with bits of points have power to do so. I think whole purpose of having forum is to share knowledge but by closing it down we are not helping it.Wolfe
Y
71

The traditional wisdom is that constructors taking one parameter (explicitly or effectively through the use of default parameters) should be marked explicit, unless they do define a conversion (std::string being convertible from const char* being one example of the latter). You've figured out the reasons yourself, in that implicit conversions can indeed make life harder than it has to be.

A perhaps obvious exception to that would be the copy constructor. Or perhaps another way is to consider that most types are convertible from and to themselves, and that as such the copy constructor is not marked explicit most of the time.

While it may appear that marking all other kinds of constructors explicit does not hurt, I'd argue against it. Because while explicit has no effect on a constructor taking multiple arguments in C++03, it does have an effect in C++11. To put it into code:

struct foo {
    explicit foo(int i);
    foo(int i, int j);
    explicit foo(int i, int j, int k);
};

foo make_foo()
{
    /* Not C++11-specific: */
    // Error: no conversion from int to foo
    return 42;

    // Okay: construction, not conversion
    return foo(42);

    // Okay: constructions
    return foo(42, 42);
    return foo(42, 42, 42);

    /* C++11 specific: */
    // Error: no conversion from int to foo
    return { 42 };

    // Not an error, not a conversion
    return { 42, 42 };

    // Error! Constructor is explicit
    return { 42, 42, 42 };
    // Not an error, direct-initialization syntax
    return foo { 42, 42, 42 };
}

I personally find it needlessly verbose that in a function that returns foo I have to explicitly return foo { 42, 42, 42 }. I don't see what explicit is protecting me from. I really want the { initializers... } syntax to mean 'construct object from given initializers', and explicit gets into the way of that while saving me from nothing. (Since { i } does boil down to i in the context of copy-initialization -- most of the time -- I'll gladly give that one up.)

So I'd say get into the habit of using explicit for unary constructors, and those only.

Yokum answered 15/9, 2012 at 12:38 Comment(3)
+1 for C++11 info I had no idea about.Educative
Necro'ing, but what about constructors with all optional parameters but the first, eg foo(int a,int b=0, int c=0). These still allow implicit conversion from an int. Is is better to mark them explicit?Bureaucratize
@Bureaucratize It’s your call, it’s your choice as the class writer whether you want construction to be explicit or not. The difference defaulted parameters make is that the same constructor does the job for construction with one, two, or three parameters. Either all those forms of construction are explicit, or none are. For finer-grained control you’ll have to split the constructor into more overloads.Yokum

© 2022 - 2024 — McMap. All rights reserved.