I came across the term explicit
being used in a C ++ code.
How useful is this keyword?
I came across the term explicit
being used in a C ++ code.
How useful is this keyword?
It is used in conjunction with the declaration of a cast operator.
I imagine you know that C ++ allows you to define operators for a type, so the syntax of certain operations gets closer than people are accustomed to traditional math or programming already used.
One of these operators is the cast , which is the conversion from one type to another. The operation can be just a reinterpretation of the data or have to change its content. It can be a simple or complex operation (turning text into number is complex).
There are two ways to use this operator, one is explicitly and the other is implicit. The way you do each one can vary. If implicit is the conversion that the compiler itself identifies that needs and calls the operator on its own. The explicit way is when the programmer put there in the code to ensure that the conversion will be done.
Since it has two operators, it has to identify when it is one and when it is the other. Explicit is determined with the keyword explicit
. The implicit is determined by a method with only 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 a int
type. It would look 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 convert.
Only available in C ++ 11 forward.
More about the cast operator.
The keyword is used in another constructor method declaration situation that requires direct initialization .
Direct initialization is the construction of an object exclusively through the syntax of methods that everyone knows about.
Indirect is a form in which initialization can occur by assigning value to the object. This is not always desirable. You can hide the fact that it's a constructor.
Then 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.
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
}