Na przykład:
operator bool() const
{
return col != 0;
}
col
jest int. Jak to operator bool() const
działa?
Na przykład:
operator bool() const
{
return col != 0;
}
col
jest int. Jak to operator bool() const
działa?
Funkcje składowe formularza
operator TypeName()
są operatorami konwersji. Pozwalają na używanie obiektów typu klasy tak, jakby były typu, TypeName
a kiedy są, są konwertowane na TypeName
użycie funkcji konwersji.
W tym konkretnym przypadku operator bool()
pozwala na użycie obiektu typu klasy tak, jakby był plikiem bool
. Na przykład, jeśli masz obiekt o nazwie typu klasy obj
, możesz go użyć jako
if (obj)
Spowoduje to wywołanie metody operator bool()
, zwróci wynik i użyje wyniku jako warunku if
.
Należy zauważyć, że operator bool()
jest to bardzo zły pomysł i naprawdę nigdy nie należy go używać. Szczegółowe wyjaśnienie, dlaczego jest to złe, oraz rozwiązanie problemu, zobacz „The Safe Bool Idiom”.
(C ++ 0x, nadchodząca wersja standardu C ++, dodaje obsługę jawnych operatorów konwersji. Umożliwiają one napisanie sejfu, explicit operator bool()
który działa poprawnie bez konieczności przeskakiwania przez obręcze implementacji idiomu Safe Bool).
bool
), nie, nie możesz jej przypisać. Gdyby była to modyfikowalna lwartość (np.bool&
), Można by do niej przypisać. Jeśli chodzi o poprawność, twierdzę, że anoperator bool()
jest zawsze niepoprawne, ponieważ pozwala na użycie obiektu typu klasy w ogromnej liczbie sytuacji, w których nigdy nie chcesz go używać. Safe Bool to znacznie lepsza alternatywa.explicit operator bool()
. Czy dobrze rozumiem?operator bool() const { return col != 0; }
Definiuje, w jaki sposób klasa jest konwertowana na wartość logiczną,
const
po znaku()
jest używany do wskazania, że ta metoda nie podlega mutacji (zmianie członków tej klasy).Zwykle używałbyś takich operatorów w następujący sposób:
airplaysdk sdkInstance; if (sdkInstance) { std::cout << "Instance is active" << std::endl; } else { std::cout << "Instance is in-active error!" << std::endl; }
źródło
Chciałbym podać więcej kodów, aby było jasne.
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 }
źródło
Zdefiniowany przez użytkownika jest to
implicit
funkcja konwersji do konwertowania klasę na albotrue
albofalse
.//usage bool value = yourclassinstance; //yourclassinstance is converted into bool!
źródło
Jest to niejawna konwersja do
bool
. To znaczy wszędzie tam, gdzie są dozwolone niejawne konwersje, Twoja klasa może zostać przekonwertowanabool
przez wywołanie tej metody.źródło
Jak powiedzieli inni, służy do konwersji typów, w tym przypadku do pliku
bool
. Na przykład:class A { bool isItSafe; public: operator bool() const { return isItSafe; } ... };
Teraz mogę użyć obiektu tej klasy tak, jakby był to wartość logiczna:
A a; ... if (a) { .... }
źródło
Pisząc swój własny unique_ptr, znalazłem ten przypadek. Biorąc
std::unique_ptr
„soperator==
: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;
I ten przypadek testowy z libstdcxx :
std::unique_ptr<int> ptr; if (ptr == 0) { } if (0 == ptr) { } if (ptr != 0) { } if (0 != ptr) { }
Uwaga, ponieważ
ptr
maexplicit operator bool() const noexcept;
, więcoperator overload resolution
działa dobrze, np.ptr == 0
Wybieratemplate <class T, class D> bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;`.
Jeśli nie ma
explicit
słowa kluczowego tutaj,ptr
wptr == 0
zostanie przekształconybool
, a następniebool
zostanie przekształconaint
, ponieważbool operator==(int, int)
jest wbudowane i0
jestint
. To, co na nas czeka, to niejednoznaczny błąd rozwiązywania problemów.Oto przykład minimalny, kompletny i weryfikowalny :
#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 | ^~~~~~~~
brzęk :
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.
źródło
Innym typowym zastosowaniem kontenerów std jest porównanie równości wartości kluczy wewnątrz obiektów niestandardowych
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; };
źródło
operator ()
nie używaoperator bool
. Są zupełnie inni.operator ()
jest operatorem połączenia, więc aComparer
można wywołać jako funkcję. Tooperator ()
po prostu powracabool
, ale to nie czyni go tym samymoperator bool
, co, co po prostu pozwala na niejawne rzutowaniebool
.