Por exemplo:
operator bool() const
{
return col != 0;
}
colé um int. Como operator bool() constfunciona?
Respostas:
Funções de membro do formulário
operator TypeName()
são operadores de conversão. Eles permitem que objetos do tipo de classe sejam usados como se fossem do tipo TypeNamee, quando o são, são convertidos para TypeNameusar a função de conversão.
Nesse caso específico, operator bool()permite que um objeto do tipo de classe seja usado como se fosse um bool. Por exemplo, se você tiver um objeto do tipo de classe chamado obj, você pode usá-lo como
if (obj)
Isso chamará o operator bool(), retornará o resultado e usará o resultado como a condição do if.
Deve-se notar que operator bool()é uma ideia muito ruim e você realmente nunca deve usá-la. Para uma explicação detalhada de por que isso é ruim e para a solução do problema, consulte "The Safe Bool Idiom".
(C ++ 0x, a próxima revisão do Padrão C ++, adiciona suporte para operadores de conversão explícitos. Eles permitirão que você escreva um cofre explicit operator bool()que funcione corretamente sem ter que pular para implementar o Idiom Bool Seguro.)
bool), não, você não pode atribuir a ele. Se fosse um lvalue modificável (por exemplo bool&), você poderia atribuí-lo. Quanto à correção, argumento que an operator bool()é sempre incorreto porque permite o uso de um objeto do tipo classe em um grande número de situações em que você nunca quer que ele seja usado. Safe Bool é uma alternativa muito superior.
explicit operator bool(). Eu compreendo corretamente?
operator bool() const
{
return col != 0;
}
Define como a classe pode ser convertida em um valor booleano, o constdepois que ()é usado para indicar que este método não sofre mutação (altera os membros desta classe).
Você normalmente usaria esses operadores da seguinte maneira:
airplaysdk sdkInstance;
if (sdkInstance) {
std::cout << "Instance is active" << std::endl;
} else {
std::cout << "Instance is in-active error!" << std::endl;
}
Eu gostaria de dar mais códigos para deixar isso claro.
struct A
{
operator bool() const { return true; }
};
struct B
{
explicit operator bool() const { return true; }
};
int main()
{
A a1;
if (a1) cout << "true" << endl; // OK: A::operator bool()
bool na1 = a1; // OK: copy-initialization selects A::operator bool()
bool na2 = static_cast<bool>(a1); // OK: static_cast performs direct-initialization
B b1;
if (b1) cout << "true" << endl; // OK: B::operator bool()
// bool nb1 = b1; // error: copy-initialization does not consider B::operator bool()
bool nb2 = static_cast<bool>(b1); // OK: static_cast performs direct-initialization
}
É uma conversão implícita para bool. Ou seja, sempre que conversões implícitas são permitidas, sua classe pode ser convertida boolchamando esse método.
Como os outros já disseram, é para conversão de tipo, neste caso para a bool. Por exemplo:
class A {
bool isItSafe;
public:
operator bool() const
{
return isItSafe;
}
...
};
Agora posso usar um objeto desta classe como se fosse um booleano:
A a;
...
if (a) {
....
}
Ao escrever meu próprio unique_ptr, encontrei este caso. Dado std::unique_ptréoperator== :
template<class T1, class D1, class T2, class D2>
bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
template <class T, class D>
bool operator==(nullptr_t, const unique_ptr<T, D>& x) noexcept;
E este caso de teste de libstdcxx :
std::unique_ptr<int> ptr;
if (ptr == 0)
{ }
if (0 == ptr)
{ }
if (ptr != 0)
{ }
if (0 != ptr)
{ }
Observe porque ptrtem um explicit operator bool() const noexcept;, então operator overload resolutionfunciona bem aqui, por exemplo, ptr == 0escolhe
template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;`.
Se não houver nenhuma explicitpalavra-chave aqui, ptrin ptr == 0será convertido em bool, então boolserá convertido em int, porque bool operator==(int, int)está integrado e 0é int. O que está esperando por nós é um erro ambíguo de resolução de sobrecarga.
Aqui está um exemplo mínimo, completo e verificável :
#include <cstddef>
struct A
{
constexpr A(std::nullptr_t) {}
operator bool()
{
return true;
}
};
constexpr bool operator ==(A, A) noexcept
{
return true;
}
constexpr bool operator ==(A, std::nullptr_t) noexcept
{
return true;
}
constexpr bool operator ==(std::nullptr_t, A) noexcept
{
return true;
}
int main()
{
A a1(nullptr);
A a2(0);
a1 == 0;
}
gcc :
prog.cc: In function 'int main()':
prog.cc:30:8: error: ambiguous overload for 'operator==' (operand types are 'A' and 'int')
30 | a1 == 0;
| ~~ ^~ ~
| | |
| A int
prog.cc:30:8: note: candidate: 'operator==(int, int)' <built-in>
30 | a1 == 0;
| ~~~^~~~
prog.cc:11:16: note: candidate: 'constexpr bool operator==(A, A)'
11 | constexpr bool operator ==(A, A) noexcept
| ^~~~~~~~
prog.cc:16:16: note: candidate: 'constexpr bool operator==(A, std::nullptr_t)'
16 | constexpr bool operator ==(A, std::nullptr_t) noexcept
| ^~~~~~~~
clang :
prog.cc:30:8: error: use of overloaded operator '==' is ambiguous (with operand types 'A' and 'int')
a1 == 0;
~~ ^ ~
prog.cc:16:16: note: candidate function
constexpr bool operator ==(A, std::nullptr_t) noexcept
^
prog.cc:11:16: note: candidate function
constexpr bool operator ==(A, A) noexcept
^
prog.cc:30:8: note: built-in candidate operator==(int, int)
a1 == 0;
^
prog.cc:30:8: note: built-in candidate operator==(float, int)
prog.cc:30:8: note: built-in candidate operator==(double, int)
prog.cc:30:8: note: built-in candidate operator==(long double, int)
prog.cc:30:8: note: built-in candidate operator==(__float128, int)
prog.cc:30:8: note: built-in candidate operator==(int, float)
prog.cc:30:8: note: built-in candidate operator==(int, double)
prog.cc:30:8: note: built-in candidate operator==(int, long double)
prog.cc:30:8: note: built-in candidate operator==(int, __float128)
prog.cc:30:8: note: built-in candidate operator==(int, long)
prog.cc:30:8: note: built-in candidate operator==(int, long long)
prog.cc:30:8: note: built-in candidate operator==(int, __int128)
prog.cc:30:8: note: built-in candidate operator==(int, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(int, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(int, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(int, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(long, int)
prog.cc:30:8: note: built-in candidate operator==(long long, int)
prog.cc:30:8: note: built-in candidate operator==(__int128, int)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, int)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, int)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, int)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, int)
prog.cc:30:8: note: built-in candidate operator==(float, float)
prog.cc:30:8: note: built-in candidate operator==(float, double)
prog.cc:30:8: note: built-in candidate operator==(float, long double)
prog.cc:30:8: note: built-in candidate operator==(float, __float128)
prog.cc:30:8: note: built-in candidate operator==(float, long)
prog.cc:30:8: note: built-in candidate operator==(float, long long)
prog.cc:30:8: note: built-in candidate operator==(float, __int128)
prog.cc:30:8: note: built-in candidate operator==(float, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(float, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(float, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(float, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(double, float)
prog.cc:30:8: note: built-in candidate operator==(double, double)
prog.cc:30:8: note: built-in candidate operator==(double, long double)
prog.cc:30:8: note: built-in candidate operator==(double, __float128)
prog.cc:30:8: note: built-in candidate operator==(double, long)
prog.cc:30:8: note: built-in candidate operator==(double, long long)
prog.cc:30:8: note: built-in candidate operator==(double, __int128)
prog.cc:30:8: note: built-in candidate operator==(double, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(double, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(double, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(double, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(long double, float)
prog.cc:30:8: note: built-in candidate operator==(long double, double)
prog.cc:30:8: note: built-in candidate operator==(long double, long double)
prog.cc:30:8: note: built-in candidate operator==(long double, __float128)
prog.cc:30:8: note: built-in candidate operator==(long double, long)
prog.cc:30:8: note: built-in candidate operator==(long double, long long)
prog.cc:30:8: note: built-in candidate operator==(long double, __int128)
prog.cc:30:8: note: built-in candidate operator==(long double, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(long double, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(long double, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(long double, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(__float128, float)
prog.cc:30:8: note: built-in candidate operator==(__float128, double)
prog.cc:30:8: note: built-in candidate operator==(__float128, long double)
prog.cc:30:8: note: built-in candidate operator==(__float128, __float128)
prog.cc:30:8: note: built-in candidate operator==(__float128, long)
prog.cc:30:8: note: built-in candidate operator==(__float128, long long)
prog.cc:30:8: note: built-in candidate operator==(__float128, __int128)
prog.cc:30:8: note: built-in candidate operator==(__float128, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(__float128, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(__float128, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(__float128, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(long, float)
prog.cc:30:8: note: built-in candidate operator==(long, double)
prog.cc:30:8: note: built-in candidate operator==(long, long double)
prog.cc:30:8: note: built-in candidate operator==(long, __float128)
prog.cc:30:8: note: built-in candidate operator==(long, long)
prog.cc:30:8: note: built-in candidate operator==(long, long long)
prog.cc:30:8: note: built-in candidate operator==(long, __int128)
prog.cc:30:8: note: built-in candidate operator==(long, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(long, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(long, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(long, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(long long, float)
prog.cc:30:8: note: built-in candidate operator==(long long, double)
prog.cc:30:8: note: built-in candidate operator==(long long, long double)
prog.cc:30:8: note: built-in candidate operator==(long long, __float128)
prog.cc:30:8: note: built-in candidate operator==(long long, long)
prog.cc:30:8: note: built-in candidate operator==(long long, long long)
prog.cc:30:8: note: built-in candidate operator==(long long, __int128)
prog.cc:30:8: note: built-in candidate operator==(long long, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(long long, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(long long, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(long long, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(__int128, float)
prog.cc:30:8: note: built-in candidate operator==(__int128, double)
prog.cc:30:8: note: built-in candidate operator==(__int128, long double)
prog.cc:30:8: note: built-in candidate operator==(__int128, __float128)
prog.cc:30:8: note: built-in candidate operator==(__int128, long)
prog.cc:30:8: note: built-in candidate operator==(__int128, long long)
prog.cc:30:8: note: built-in candidate operator==(__int128, __int128)
prog.cc:30:8: note: built-in candidate operator==(__int128, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(__int128, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(__int128, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(__int128, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, float)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, double)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, long double)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, __float128)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, long)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, long long)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, __int128)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(unsigned int, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, float)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, double)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, long double)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, __float128)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, long)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, long long)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, __int128)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(unsigned long, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, float)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, double)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, long double)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, __float128)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, long)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, long long)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, __int128)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(unsigned long long, unsigned __int128)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, float)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, double)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, long double)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, __float128)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, long)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, long long)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, __int128)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, unsigned int)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, unsigned long)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, unsigned long long)
prog.cc:30:8: note: built-in candidate operator==(unsigned __int128, unsigned __int128)
1 error generated.
Outro uso comum é para contêineres std fazer comparação de igualdade em valores-chave dentro de objetos personalizados
class Foo
{
public: int val;
};
class Comparer { public:
bool operator () (Foo& a, Foo&b) const {
return a.val == b.val;
};
class Blah
{
std::set< Foo, Comparer > _mySet;
};
operator ()não operator bool. Eles são totalmente diferentes. operator ()é o operador de chamada, para que a Comparerpossa ser chamado como uma função. Isso operator ()apenas acontece para retornar bool, mas isso não o torna o mesmo que operator bool, o que simplesmente permite uma conversão implícita para bool.