3

Is using the cast constructor bad? Otherweise why a code quality checker (cppcheck in my case) would constantly suggest to add explicit before single parameter constructors?

What if I want to do

class MyClass {  
 A(int) {}
};

A a = 1;

If I follow the "suggestions" and write

class MyClass {  
 explicit A(int) {}
};

A a = 1; 

would throw an error, but if I use the first I'll have a warning that i've to document to pass the code reviews.

ks1322
  • 33,961
  • 14
  • 109
  • 164
DDS
  • 2,340
  • 16
  • 34
  • Checkers like cppcheck check against *style* guidelines. Some style guidelines discourage use of single-argument "cast" constructors, and encourage making them explicit, because doing so avoids unintended implicit conversions. The point of such style guidelines is *requiring* you to document an explicit justification for implicit casting constructors whenever you use them. – Peter Dec 22 '20 at 09:39
  • The direct solution is to initialize with `A a{1};` – stefaanv Dec 22 '20 at 09:51
  • You might disable the check locally, see for example [cppcheck-inline-suppression](https://stackoverflow.com/questions/37701104/cppcheck-inline-suppression-not-working). – Jarod42 Dec 22 '20 at 13:13
  • See also: [Should I really massively introduce the explicit keyword?](https://stackoverflow.com/questions/30052326/should-i-really-massively-introduce-the-explicit-keyword) – Wolf Aug 29 '22 at 10:47

2 Answers2

6

C++ Core Guidelines

C.46: By default, declare single-argument constructors explicit

Reason

To avoid unintended conversions.

Example, bad

class String {
public:
    String(int);   // BAD
    // ...
};

String s = 10;   // surprise: string of size 10

Exception

If you really want an implicit conversion from the constructor argument type to the class type, don't use explicit:

class Complex {
public:
    Complex(double d);   // OK: we want a conversion from d to {d, 0}
    // ...
};

Complex z = 10.7;   // unsurprising conversion

See also: Discussion of implicit conversions

bolov
  • 72,283
  • 15
  • 145
  • 224
5

Such implicit class type conversion can be used easily without intention. With this converting constructor every function or member function which accepts MyClass as argument will accept also int. Therefore every int passed to such a function will be converted to a temporary MyClass which will be discarded after the function has finished. Probably not what you want.

Peter
  • 2,240
  • 3
  • 23
  • 37