An explicit constructor is a constructor which can’t be used as converting constructor. We can create explicit constructor using explicit keyword.
Note
Making constructors
explicitdoes two things:
- explicit constructor can’t be used for copy initialization or copy list initialization.
- explicit constructor can’t be used for implicit conversions (since it uses copy initialization or copy list initialization)
For example,
#include <iostream>
class Int
{
private:
int m_value{};
public:
Int() = default;
explicit Int(int value)
: m_value{value}
{
}
void print()
{
std::cout << "Int(" << m_value << ")\n";
}
};
void printInt(Int value)
{
value.print();
}
int main(int argc, char const *argv[])
{
printInt(2); // should throw compilation error
printInt({2}); // error: copy list initialization not supported
Int i = {1}; // error: copy list initialization not supported
return 0;
}Above program should throw compilation error.
We can solve this by explicitly creating Int and passing to the function, as direct or direct list initialization is still supported. For example,
printInt(Int{1});Explicit constructors and return by value
If the type of returning value does not match with the return type, an implicit conversion takes place. If constructors are explicit, it will throw error. For example,
Int getInt()
{
return Int{1}; // works: passing Int explicitly.
return {1}; // fails: copy list initialization unsupported.
return 1; // fails: implicit conversion unsupported
}