ตัวอย่างเช่น:
operator bool() const
{
return col != 0;
}
col
เป็น int วิธีการoperator bool() const
ทำงานหรือไม่
ตัวอย่างเช่น:
operator bool() const
{
return col != 0;
}
col
เป็น int วิธีการoperator bool() const
ทำงานหรือไม่
คำตอบ:
ฟังก์ชันสมาชิกของแบบฟอร์ม
operator TypeName()
เป็นตัวดำเนินการแปลง อนุญาตให้ใช้อ็อบเจ็กต์ประเภทคลาสราวกับว่าเป็นประเภทTypeName
และเมื่อเป็นเช่นนั้นพวกเขาจะถูกแปลงเป็นการTypeName
ใช้ฟังก์ชันการแปลง
ในกรณีนี้operator bool()
อนุญาตให้ใช้อ็อบเจ็กต์ประเภทคลาสราวกับว่าเป็นไฟล์bool
. ตัวอย่างเช่นหากคุณมีออบเจ็กต์ประเภทคลาสที่ตั้งชื่อobj
คุณสามารถใช้เป็น
if (obj)
สิ่งนี้จะเรียกใช้operator bool()
ส่งคืนผลลัพธ์และใช้ผลลัพธ์เป็นเงื่อนไขของif
.
ควรสังเกตว่าoperator bool()
เป็นความคิดที่แย่มากและคุณไม่ควรใช้มันเลย สำหรับคำอธิบายโดยละเอียดว่าเหตุใดจึงไม่ดีและสำหรับวิธีแก้ไขปัญหาโปรดดู"The Safe Bool Idiom"
(C ++ 0x ซึ่งเป็นการแก้ไขมาตรฐาน C ++ ที่กำลังจะมีขึ้นเพิ่มการสนับสนุนสำหรับตัวดำเนินการแปลงอย่างชัดเจนสิ่งเหล่านี้จะช่วยให้คุณสามารถเขียนตู้นิรภัยexplicit operator bool()
ที่ทำงานได้อย่างถูกต้องโดยไม่ต้องข้ามห่วงการใช้งาน Safe Bool Idiom)
bool
) ไม่คุณจึงไม่สามารถกำหนดให้ได้ หากเป็นค่า lvalue ที่ปรับเปลี่ยนได้ (เช่นbool&
) คุณสามารถกำหนดให้ได้ สำหรับความถูกต้องฉันยืนยันว่า an operator bool()
ไม่ถูกต้องเสมอเพราะอนุญาตให้ใช้ออบเจ็กต์ประเภทคลาสในสถานการณ์จำนวนมากที่คุณไม่ต้องการใช้ Safe Bool เป็นทางเลือกที่เหนือกว่า
explicit operator bool()
ดังนั้นตามวรรคสุดท้ายวันนี้เป็นวันที่ดีที่สุดที่ตกลงเพื่อการใช้งาน ฉันเข้าใจถูกต้องหรือไม่?
operator bool() const
{
return col != 0;
}
กำหนดว่าคลาสสามารถแปลงเป็นค่าบูลีนได้อย่างไรconst
หลังจากที่()
ใช้เพื่อระบุวิธีนี้จะไม่กลายพันธุ์ (เปลี่ยนสมาชิกของคลาสนี้)
โดยปกติคุณจะใช้ตัวดำเนินการดังต่อไปนี้:
airplaysdk sdkInstance;
if (sdkInstance) {
std::cout << "Instance is active" << std::endl;
} else {
std::cout << "Instance is in-active error!" << std::endl;
}
ฉันต้องการให้รหัสเพิ่มเติมเพื่อให้ชัดเจน
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
}
เป็นimplicit
ฟังก์ชันการแปลงที่ผู้ใช้กำหนดเองเพื่อแปลงคลาสของคุณเป็นtrue
หรือfalse
.
//usage
bool value = yourclassinstance; //yourclassinstance is converted into bool!
bool
มันเป็นแปลงนัยไป เช่นเมื่อใดก็ตามที่อนุญาตให้มีการแปลงโดยนัยชั้นเรียนของคุณสามารถแปลงเป็นbool
โดยเรียกใช้วิธีการนั้น
ดังที่คนอื่น ๆ กล่าวไว้สำหรับการแปลงประเภทในกรณีนี้เป็นbool
ไฟล์. ตัวอย่างเช่น:
class A {
bool isItSafe;
public:
operator bool() const
{
return isItSafe;
}
...
};
ตอนนี้ฉันสามารถใช้ออบเจ็กต์ของคลาสนี้ราวกับว่ามันเป็นบูลีน:
A a;
...
if (a) {
....
}
เมื่อเขียน unique_ptr ของฉันเองฉันพบกรณีนี้ ได้รับ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;
และกรณีทดสอบจากlibstdcxx :
std::unique_ptr<int> ptr;
if (ptr == 0)
{ }
if (0 == ptr)
{ }
if (ptr != 0)
{ }
if (0 != ptr)
{ }
สังเกตว่าptr
มี a explicit operator bool() const noexcept;
จึงoperator overload resolution
ใช้ได้ดีที่นี่เช่นptr == 0
เลือก
template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;`.
หากไม่มีexplicit
คำหลักที่นี่ptr
ในptr == 0
จะถูกแปลงเป็นbool
จากนั้นbool
จะถูกแปลงเป็นint
เพราะbool operator==(int, int)
มีอยู่แล้วภายในและ0
เป็นint
เป็นสิ่งที่รอเราอยู่คือข้อผิดพลาดในการแก้ปัญหาโอเวอร์โหลดที่ไม่ชัดเจน
นี่คือตัวอย่างขั้นต่ำสมบูรณ์และตรวจสอบได้ :
#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
| ^~~~~~~~
เสียงดัง :
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.
การใช้งานทั่วไปอีกอย่างหนึ่งสำหรับคอนเทนเนอร์ std เพื่อทำการเปรียบเทียบความเท่าเทียมกันของค่าคีย์ภายในออบเจ็กต์ที่กำหนดเอง
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 ()
operator bool
พวกเขาแตกต่างกันโดยสิ้นเชิง operator ()
เป็นตัวดำเนินการโทรเพื่อให้Comparer
สามารถเรียกใช้เป็นฟังก์ชันได้ สิ่งนี้operator ()
เกิดขึ้นเพื่อกลับมาbool
แต่นั่นไม่ได้ทำให้มันเหมือนกับoperator bool
ที่อนุญาตให้ส่งโดยปริยายbool
ได้