Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ always use explicit constructor [closed]

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.

like image 219
oopsi Avatar asked Sep 15 '12 12:09

oopsi


People also ask

Why is explicit used for constructors?

The explicit function specifier controls unwanted implicit type conversions. It can only be used in declarations of constructors within a class declaration. For example, except for the default constructor, the constructors in the following class are conversion constructors.

Should default constructor be explicit?

A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization or value initialization (8.5). It goes on to provide an example of an explicit default constructor, but it simply mimics the example I provided above.

What does explicit constructor mean in C++?

The explicit keyword in C++ is used to mark constructors to not implicitly convert types. For example, if you have a class Foo − class Foo { public: Foo(int n); // allocates n bytes to the Foo object Foo(const char *p); // initialize object with char *p };

Can constructor be called implicitly?

A constructor is a special member function that is automatically called by the compiler when an object is created and the destructor is also a special member function that is also implicitly called by the compiler when the object goes out of scope.


1 Answers

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.

like image 125
Luc Danton Avatar answered Sep 24 '22 05:09

Luc Danton