Sebagai contoh:
operator bool() const
{
return col != 0;
}
col
adalah int. Bagaimana cara operator bool() const
kerjanya?
Jawaban:
Fungsi anggota formulir
operator TypeName()
adalah operator konversi. Mereka memungkinkan objek dari tipe kelas untuk digunakan seolah-olah mereka bertipe TypeName
dan ketika mereka dikonversi TypeName
menggunakan fungsi konversi.
Dalam kasus khusus ini, operator bool()
memungkinkan objek dari tipe kelas untuk digunakan seolah-olah itu adalah a bool
. Misalnya, jika Anda memiliki sebuah objek dari tipe kelas bernama obj
, Anda dapat menggunakannya sebagai
if (obj)
Ini akan memanggil operator bool()
, mengembalikan hasil, dan menggunakan hasil sebagai kondisi if
.
Perlu dicatat bahwa itu operator bool()
adalah Ide yang Sangat Buruk dan Anda tidak boleh menggunakannya. Untuk penjelasan rinci tentang mengapa hal itu buruk dan untuk solusi dari masalah tersebut, lihat "The Safe Bool Idiom."
(C ++ 0x, revisi C ++ Standard yang akan datang, menambahkan dukungan untuk operator konversi eksplisit. Ini akan memungkinkan Anda menulis brankas explicit operator bool()
yang berfungsi dengan benar tanpa harus melewati rintangan dalam mengimplementasikan Safe Bool Idiom.)
bool
), tidak, Anda tidak dapat menetapkannya. Jika itu adalah nilai l yang dapat dimodifikasi (misalnya bool&
) maka Anda dapat menetapkannya. Mengenai kebenaran, saya berpendapat bahwa an operator bool()
selalu salah karena memungkinkan penggunaan objek tipe kelas dalam sejumlah besar situasi di mana Anda tidak pernah menginginkannya digunakan. Safe Bool adalah alternatif yang jauh lebih unggul.
explicit operator bool()
. Apakah saya mengerti dengan benar?
operator bool() const
{
return col != 0;
}
Mendefinisikan bagaimana kelas dapat diubah menjadi nilai boolean, const
setelah ()
digunakan untuk menunjukkan metode ini tidak bermutasi (ubah anggota kelas ini).
Biasanya Anda akan menggunakan operator seperti berikut:
airplaysdk sdkInstance;
if (sdkInstance) {
std::cout << "Instance is active" << std::endl;
} else {
std::cout << "Instance is in-active error!" << std::endl;
}
Saya ingin memberikan lebih banyak kode untuk membuatnya jelas.
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
}
Ini adalah konversi implisit menjadi bool
. Yaitu di mana pun konversi implisit diizinkan, kelas Anda dapat dikonversi bool
dengan memanggil metode itu.
Seperti yang dikatakan orang lain, ini untuk konversi tipe, dalam hal ini menjadi bool
. Sebagai contoh:
class A {
bool isItSafe;
public:
operator bool() const
{
return isItSafe;
}
...
};
Sekarang saya dapat menggunakan objek dari kelas ini seolah-olah itu adalah boolean:
A a;
...
if (a) {
....
}
Saat menulis unique_ptr saya sendiri, saya menemukan kasus ini. Mengingat 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;
Dan kasus uji ini dari libstdcxx :
std::unique_ptr<int> ptr;
if (ptr == 0)
{ }
if (0 == ptr)
{ }
if (ptr != 0)
{ }
if (0 != ptr)
{ }
Perhatikan karena yang ptr
memiliki explicit operator bool() const noexcept;
, jadi operator overload resolution
berfungsi dengan baik di sini, misalnya, ptr == 0
pilih
template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;`.
Jika tidak ada explicit
kata kunci di sini, ptr
in ptr == 0
akan diubah menjadi bool
, kemudian bool
akan diubah menjadi int
, karena bool operator==(int, int)
sudah built-in dan 0
ada int
. Yang menunggu kami adalah kesalahan resolusi overload yang ambigu.
Berikut adalah contoh Minimal, Lengkap, dan Dapat Diverifikasi :
#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
| ^~~~~~~~
dentang :
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.
Penggunaan umum lainnya adalah untuk kontainer std untuk melakukan perbandingan kesetaraan pada nilai kunci di dalam objek khusus
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 ()
tidak operator bool
. Mereka sangat berbeda. operator ()
adalah operator panggilan, sehingga a Comparer
bisa disebut sebagai fungsi. Itu operator ()
kebetulan kembali bool
, tetapi itu tidak membuatnya sama seperti operator bool
, yang hanya memungkinkan untuk transmisi implisit bool
.