C++ Keywords - explicit
Implicit conversions allow an object of one type (called the source type) to be used where a different type (called the destination type) is expected, such as when passing an int argument to a function that takes a double parameter.
The explicit keyword can be applied to a constructor or a conversion operator, to ensure that it can only be used when the destination type is explicit at the point of use, e.g., with a cast. This applies not only to implicit conversions, but to list initialization syntax:
class Foo {
explicit Foo(int x, double y);
...
};
void Func(Foo f);
Func({42, 3.14}); // Error
Best Practice
TL;DR: Most constructors should be explicit.
- Implicit Conversions: Prior to C++11, the
explicitkeyword was primarily used for single-argument constructors to prevent implicit type conversions. However, with C++11, theexplicitkeyword's meaning expanded to include multi-parameter constructors. This means that multi-parameter constructors can also be involved in implicit conversions, which is why the guidance should be applied to multi-argument constructors as well. - Preventing Unintentional Conversions: The
explicitkeyword is used to prevent unintentional type conversions. When a constructor is marked asexplicit, it requires the programmer to explicitly specify the constructor call, which helps to avoid accidental implicit conversions. This is especially useful when a constructor can be called with multiple arguments that could be interpreted in multiple ways. - Explicit Construction: When a constructor is marked as
explicit, it forces the use of the constructor syntax (e.g., ClassName(arg1, arg2)) rather than relying on implicit conversion. This makes the code more explicit and less prone to ambiguity, especially when the arguments could be interpreted as different types. - Copy Initialization: In C++11,
explicitbecame meaningful for copy-initialization from braced lists, such as when calling a functionvoid f(std::pair)withf({1, 2})or when initializing a variable bad withstd::vector bad = {"hello", "world"}. - Value vs. Recipe: The
explicitkeyword should be used when the constructor is not simply creating a value, but rather a recipe for a value. For example, if the arguments are not the value of the newly created object, the constructor should be explicit.