cpp
explicit

What does the explicit keyword mean?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C++, the explicit keyword tells the compiler not to use a constructor or conversion operator for implicit conversions in contexts where that conversion would otherwise be allowed. Its job is to force the programmer to spell out intent instead of letting type changes happen silently.

Why Implicit Conversions Can Be Risky

A constructor that can be called with one argument often becomes an implicit conversion path unless you mark it explicit.

cpp
1#include <iostream>
2
3class Distance {
4public:
5    Distance(int meters) : meters_(meters) {}
6
7    int meters() const { return meters_; }
8
9private:
10    int meters_;
11};
12
13void print_distance(const Distance& d) {
14    std::cout << d.meters() << "\n";
15}
16
17int main() {
18    print_distance(5);  // int converts implicitly to Distance
19}

That may look convenient, but it also hides conversions at call sites and can create surprising overload behavior.

What explicit Changes

Marking the constructor explicit blocks those implicit conversions.

cpp
1#include <iostream>
2
3class Distance {
4public:
5    explicit Distance(int meters) : meters_(meters) {}
6
7    int meters() const { return meters_; }
8
9private:
10    int meters_;
11};
12
13void print_distance(const Distance& d) {
14    std::cout << d.meters() << "\n";
15}
16
17int main() {
18    // print_distance(5);        // error
19    print_distance(Distance(5)); // OK
20}

Now the conversion must be written explicitly, which makes the code easier to reason about.

Direct Initialization Versus Copy Initialization

A useful mental model is:

  • direct initialization can call an explicit constructor
  • copy initialization cannot use it implicitly

So Distance d(5); is valid, while Distance d = 5; is not if the constructor is explicit.

That difference is exactly the point. Construction is still allowed, but accidental conversion-style syntax is rejected.

explicit Also Applies to Conversion Operators

The keyword is not limited to constructors. It also works on conversion operators.

cpp
1class Flag {
2public:
3    explicit operator bool() const {
4        return true;
5    }
6};

This is useful when a type should support explicit tests but should not quietly convert in every arithmetic or overload context.

Why Library Types Use It Heavily

Well-designed C++ libraries rely on explicit because APIs age poorly when they accept too many silent conversions. A class that seems simple today may later gain overloads or more complex invariants. Preventing implicit conversions early reduces future ambiguity.

That is why many modern style guides recommend making single-argument constructors explicit by default unless implicit conversion is a deliberate part of the type's design.

A Practical Rule of Thumb

Ask this question: should an object of this type appear automatically anywhere the source value appears?

If the answer is no, use explicit.

If the answer is yes, and that implicit conversion is central to the type's meaning, you may leave it implicit. But that should be a conscious decision, not an accident.

Why Modern C++ Code Uses It Frequently

Modern C++ APIs try to avoid surprising conversions because those surprises compound over time as overloads and helper types accumulate. Marking constructors explicit by default is a defensive design habit: it keeps object creation intentional and leaves fewer hidden conversion paths for the compiler to consider later.

Common Pitfalls

A common mistake is forgetting that single-argument constructors become conversion paths when not marked explicit.

Another mistake is assuming explicit blocks all construction. It does not. It blocks implicit conversion contexts, not direct construction.

It is also easy to overlook conversion operators, which can cause the same kind of hidden behavior if left implicit.

Summary

  • 'explicit prevents certain implicit conversions in C++.'
  • It is commonly used on single-argument constructors and conversion operators.
  • Direct construction still works, but implicit copy-style conversion does not.
  • The keyword makes call sites clearer and overload behavior more predictable.
  • Use it by default unless silent conversion is truly part of the type's intended design.

Course illustration
Course illustration

All Rights Reserved.