Question
In C++, what does the explicit keyword mean, and how does it affect constructors or conversion behavior?
Short Answer
By the end of this page, you will understand what explicit does in C++, why it is used to prevent unwanted implicit conversions, where it can be applied, and how to use it correctly with constructors and conversion operators.
Concept
In C++, the explicit keyword tells the compiler not to use a constructor or conversion operator for implicit conversions.
This matters because C++ can automatically convert one type into another in some situations. That can be convenient, but it can also create confusing bugs when a value is converted in a way you did not intend.
A very common case is a constructor that takes one parameter. Without explicit, that constructor can often be used as an implicit converting constructor.
For example:
class Distance {
public:
Distance(int meters) {}
};
void printDistance(Distance d) {}
int main() {
printDistance(5); // allowed: int is implicitly converted to Distance
}
Here, 5 is not a Distance, but C++ silently creates a Distance(5) object.
If that constructor is marked explicit, the compiler will refuse the automatic conversion:
class Distance {
public:
explicit Distance(int meters) {}
};
void printDistance(Distance d) {}
int main() {
printDistance(5); // error
printDistance(Distance(5)); // OK
}
Now the conversion must be written clearly.
Why this matters
explicit improves code by:
- preventing accidental conversions
- making APIs easier to understand
- reducing surprising behavior
- making code safer and more readable
Where explicit is used
In modern C++, explicit is mainly used with:
- constructors
- conversion operators
Explicit constructor
class StringSize {
public:
explicit StringSize(int n) : size(n) {}
private:
int size;
};
Explicit conversion operator
class Flag {
public:
explicit operator bool() const {
return true;
}
};
This means the object cannot automatically turn into bool in every context unless the language specifically allows that usage or you convert it explicitly.
Historical note
Traditionally, explicit was mainly associated with single-argument constructors, because those are the most obvious source of implicit conversions. In modern C++, the idea is broader: use explicit whenever you want to block automatic conversion behavior.
Mental Model
Think of explicit as a manual-only sign on a door.
Without explicit, C++ sees a constructor or conversion path and says:
- "I can convert this automatically for you."
With explicit, you are telling C++:
- "Do not do this automatically. Only do it when I clearly ask for it."
So:
- implicit conversion = automatic gearbox
- explicit conversion = manual gearbox
If a class can be created from an int, a std::string, or another type, explicit forces the programmer to say exactly when that conversion should happen. That makes the code less magical and easier to trust.
Syntax and Examples
Basic syntax
Explicit constructor
class MyType {
public:
explicit MyType(int value) {}
};
Explicit conversion operator
class MyType {
public:
explicit operator bool() const {
return true;
}
};
Example 1: Constructor without explicit
#include <iostream>
using namespace std;
class Box {
public:
Box(int size) {
cout << "Box created with size " << size << endl;
}
};
void openBox(Box b) {}
{
();
}
Step by Step Execution
Traceable example
#include <iostream>
using namespace std;
class Temperature {
public:
explicit Temperature(int c) : celsius(c) {}
int get() const {
return celsius;
}
private:
int celsius;
};
void show(Temperature t) {
cout << t.get() << "C" << endl;
}
int main() {
Temperature t1(25);
show(t1);
show(Temperature(30));
// show(30); // error
}
Step by step
- The class
Temperaturehas a constructor that takes oneint.
Real World Use Cases
1. Wrapper types
If you create a class that wraps a primitive value, such as UserId, Meter, Price, or PortNumber, you usually do not want random integers to become those types automatically.
class UserId {
public:
explicit UserId(int value) : value(value) {}
private:
int value;
};
This prevents mistakes like passing a plain int where a meaningful domain type is expected.
2. Safer APIs
Libraries often use explicit to make function calls clearer.
class Timeout {
public:
explicit Timeout(int ms) : milliseconds(ms) {}
private:
int milliseconds;
};
Then callers must write instead of just , which makes code easier to read.
Real Codebase Usage
In real C++ projects, developers often default to marking single-argument constructors as explicit unless they specifically want implicit conversion.
Common patterns
Guarding domain types
class PortNumber {
public:
explicit PortNumber(int port) : port(port) {}
private:
int port;
};
This prevents accidentally passing a plain integer into APIs that expect something more meaningful.
Validation at construction time
#include <stdexcept>
class Age {
public:
explicit Age(int value) {
if (value < 0) {
throw std::invalid_argument("Age cannot be negative");
}
age = value;
}
private:
int age;
};
Here explicit works well with validation because object creation is intentional and visible.
Common Mistakes
1. Thinking explicit prevents direct construction
explicit does not stop this:
class A {
public:
explicit A(int x) {}
};
A a(5); // OK
It only stops implicit conversion.
2. Assuming it only applies to one-argument constructors forever
Beginners often hear that explicit is for one-argument constructors. That is the classic case, but modern C++ also uses it with conversion operators.
class A {
public:
explicit operator bool() const {
return true;
}
};
3. Forgetting why implicit conversion is dangerous
Broken example:
Comparisons
explicit vs non-explicit
| Version | Implicit conversion allowed? | Readability | Safety |
|---|---|---|---|
Constructor without explicit | Yes | Lower when conversions are hidden | Lower |
Constructor with explicit | No | Higher because intent is visible | Higher |
Example comparison
Without explicit
class Size {
public:
Size(int v) : value(v) {}
private:
int value;
};
void {}
();
Cheat Sheet
Quick reference
Purpose
explicit prevents implicit conversions through constructors or conversion operators.
Common syntax
class A {
public:
explicit A(int x);
explicit operator bool() const;
};
What it blocks
class A {
public:
explicit A(int x) {}
};
void f(A a) {}
f(10); // error
f(A(10)); // OK
What it allows
;
A b{};
A c = ();
FAQ
What does explicit do in C++?
It prevents the compiler from using a constructor or conversion operator for automatic implicit conversions.
Why is explicit used with constructors?
It stops values like int or string from silently becoming objects of your class when that behavior is not intended.
Does explicit only apply to constructors?
No. It is also used with conversion operators, such as explicit operator bool() const.
Can I still create an object if the constructor is explicit?
Yes. You can still create the object directly, for example MyType x(5);. You just cannot rely on automatic conversion.
Should I always mark single-argument constructors as explicit?
That is a good default in most codebases. Only allow implicit conversion when it clearly improves the design and is safe.
What is the difference between implicit and explicit conversion?
Implicit conversion happens automatically. Explicit conversion requires the programmer to write the conversion clearly in code.
Does explicit make code safer?
Yes. It reduces accidental conversions and makes intent clearer, which helps prevent bugs.
Mini Project
Description
Build a small C++ program that models a UserId type. The project demonstrates why explicit is useful when wrapping primitive values such as integers in safer domain-specific types.
Goal
Create a type-safe UserId class that prevents accidental implicit conversion from int while still allowing clear, intentional object creation.
Requirements
- Create a
UserIdclass with a constructor that takes anint. - Mark the constructor with
explicit. - Write a function that accepts a
UserIdparameter. - Show valid direct construction and function calls.
- Include one commented line that would fail because implicit conversion is blocked.
Keep learning
Related questions
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Casts Explained: C-Style Cast vs static_cast vs dynamic_cast
Learn the difference between C-style casts, static_cast, and dynamic_cast in C++ with clear examples, safety rules, and real usage tips.
C++ Lambda Expressions Explained: What They Are and When to Use Them
Learn what C++ lambda expressions are, why they exist, when to use them, and how they simplify callbacks, algorithms, and local logic.