Question:
I came across the term explicit
being used in C++ code.
What is the use of this keyword?
Answer:
cast operator
It is used in conjunction with declaring a cast operator.
I imagine you know that C++ allows you to define operators for a type, so the syntax of certain operations is closer to what people are used to with traditional math or that already used in programming.
One of these operators is cast , which is the conversion from one type to another. The operation can be just a reinterpretation of the data or having to change its content. It can be a simple or complex operation (transforming a text into a number is complex).
There are two ways to use this operator, one is explicitly and one is implicit. How to do each can vary. If it is implicit, it is the conversion that the compiler itself identifies that it needs and calls the operator on its own. The explicit way is when the programmer put it there in the code to ensure the conversion will be done.
Since it has two operators, it has to identify when it is one and when it is the other. The explicit is determined with the explicit
keyword. The implicit is determined by a method with just the type name without a specific keyword .
operator int() const { return 0; } //obviamente é só exemplo, não está convertendo nada
This would be the cast operator for an int
type. I would use it like this:
int x = (int)variavel_do_tipo_que_tem_o_operador; //x valeria 0 nesse exemplo
Obviously you need to have an operator for each type you want to provide a cast.
It is only available in C++11 and onwards.
More about the cast operator .
Constructor
The keyword is used in another constructor method declaration situation that requiresdirect initialization .
Direct initialization is the construction of an object exclusively through the syntax of methods that everyone knows.
Indirect is one way in which initialization can occur by assigning value to the object. This is not always desirable. It can hide the fact that that's a builder.
So an explicit constructor disables indirect construction
Foo f(2); //forma explícita/direta de chamada do construtor
Foo f2 = 2; //forma implícita/indireta de chamada do construtor
Using
explicit Foo(int) { }
Only the first call would be possible.
Complete example:
struct A {
A(int) { } // construtor de conversão
A(int, int) { } // construtor de conversão (C++11)
operator int() const { return 0; } // operador de cast implícito
};
struct B {
explicit B(int) { }
explicit B(int, int) { }
explicit operator int() const { return 0; }
};
int main() {
A a1 = 1; // OK: copy-initialization chama A::A(int)
A a2(2); // OK: direct-initialization chama A::A(int)
A a3 {4, 5}; // OK: direct-list-initialization chama A::A(int, int)
A a4 = {4, 5}; // OK: copy-list-initialization chama A::A(int, int)
int na1 = a1; // OK: copy-initialization chama A::operator int()
int na2 = static_cast<int>(a1); // OK: static_cast faz a inicialização
A a5 = (A)1; // OK: explicit cast faz o static_cast
// B b1 = 1; // error: copy-initialization B::B(int) não permitida
B b2(2); // OK: direct-initialization chama B::B(int)
B b3 {4, 5}; // OK: direct-list-initialization chama B::B(int, int)
// B b4 = {4, 5}; // error: copy-list-initialization B::B(int,int) não permitida
// int nb1 = b2; // error: copy-initialization B::operator int() não permitida
int nb2 = static_cast<int>(b2); // OK: static_cast faz a inicialização
B b5 = (B)1; // OK: explicit cast faz o static_cast
}
I put it on GitHub for future reference .