"연산자 bool () const"의 의미는 무엇입니까?


답변:


141

양식의 구성원 기능

operator TypeName()

변환 연산자입니다. 클래스 유형의 객체를 마치 유형 인 것처럼 TypeName사용할 수 있으며, TypeName있는 경우 변환 함수 를 사용하여 변환됩니다.

이 특별한 경우 operator bool()에는 클래스 유형의 객체를 bool. 예를 들어라는 클래스 유형의 객체가있는 경우 다음 obj과 같이 사용할 수 있습니다.

if (obj)

이것은를 호출하고 operator bool()결과를 반환하며 결과를 if.

그것은 operator bool()매우 나쁜 생각이며 실제로 사용해서는 안됩니다. 이것이 왜 나쁜지에 대한 자세한 설명과 문제 해결 방법은 "The Safe Bool Idiom"을 참조하십시오 .

(C ++ 표준의 향후 개정판 인 C ++ 0x는 명시 적 변환 연산자에 대한 지원을 추가합니다.이를 explicit operator bool()통해 Safe Bool Idiom을 구현하는 과정을 거치지 않고도 올바르게 작동 하는 금고를 작성할 수 있습니다 .)


1
"부울 인 것처럼 사용됨"은 부울 값을 할당 할 수 있다는 잘못된 의미입니다. 오히려 포스터의 코드에서 col의 순간 값과 관련된 bool 유형의 임시 변수를 생성하지만 이후에는이를 생성 한 객체와 독립적입니다. 또한 Safe Bool Idiom에 대한 언급은 훌륭하지만 그 반대의 견해가 존재한다는 사실을 등록하는 것뿐입니다. IMHO는 "정말 사용하지 마십시오"라는 조언이 최고입니다. 더 난독 화 된 API를 사용하여 어리석은 오용에 대해 엄격한 컴파일러 검사를 제공합니다. 우발적 인 오용으로 이어질 수 있습니다.
Tony Delroy 2011 년

1
@Tony : 음, 부울 인 것처럼 사용할 수 있습니다. 변환의 결과는 rvalue ( bool)이므로 할당 할 수 없습니다. 수정 가능한 lvalue (예 :) bool&이면 할당 할 수 있습니다. 정확성에 관해서는 operator bool()절대로 사용하고 싶지 않은 수많은 상황에서 클래스 유형 객체를 사용할 수 있기 때문에 an 은 항상 올바르지 않다고 주장합니다 . Safe Bool은 훨씬 우수한 대안입니다.
James McNellis 2011 년

1
그래서 오늘 마지막 단락에 따르면 완벽하게 사용할 수 있습니다 explicit operator bool(). 내가 올바르게 이해 했습니까?
Zingam

1
C ++위원회는 bool () 연산자에 대해 동의하지 않는 것 같습니다. 최소한 최신 버전의 표준 (예 : en.cppreference.com/w/cpp/utility/optional ). 아니면 STL 코드 만 사용하도록 허용해야한다는 뜻일까요?
Joe Steele

1
@JoeSteele - 참조 stackoverflow.com/a/16615725/2492801 . 명시 적 변환 연산자는 안전합니다!
Benjamin Bihler

9
operator bool() const 
{
    return col != 0;
}

클래스가, 부울 값으로 convertable하는 방법을 정의 const가 이후 ()의 mutate (이 클래스의 멤버를 변경)하지 않습니다이 방법을 나타내는 데 사용됩니다.

일반적으로 다음과 같은 연산자를 사용합니다.

airplaysdk sdkInstance;
if (sdkInstance) {
    std::cout << "Instance is active" << std::endl;
} else {
    std::cout << "Instance is in-active error!" << std::endl;
}

7

명확하게하기 위해 더 많은 코드를 제공하고 싶습니다.

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
}

3

implicit클래스를 true또는 로 변환하는 사용자 정의 변환 함수 false입니다.

//usage
bool value = yourclassinstance; //yourclassinstance is converted into bool!

1

암시 적 변환 bool입니다. 즉, 암시 적 변환이 허용되는 모든 곳에서 bool해당 메서드를 호출 하여 클래스를 변환 할 수 있습니다 .


1

다른 사람들이 말했듯이, 이것은 유형 변환을위한 것이며,이 경우 bool. 예를 들면 :

class A {
    bool isItSafe;

public:
    operator bool() const
    {
        return isItSafe;
    }

    ...
};

이제이 클래스의 객체를 부울 인 것처럼 사용할 수 있습니다.

A a;
...
if (a) {
    ....
}

1

내 unique_ptr을 작성할 때이 경우를 발견했습니다. 주어진 std::unique_ptroperator== :

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있다 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
      |                ^~~~~~~~

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.

-4

또 다른 일반적인 용도는 표준 컨테이너가 사용자 지정 개체 내의 키 값에 대해 동일성 비교를 수행하는 것입니다.

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;
};

2
이것은 operator ()not을 사용하는 예 operator bool입니다. 그들은 완전히 다릅니다. operator ()호출 연산자이므로 Comparera를 함수로 호출 할 수 있습니다. 그것은 operator ()단지 반환되는 bool일이지만 operator bool, 그것은 단순히 암시 적 캐스트를 허용 하는 것과 동일하게 만들지 않습니다 bool.
Michael Dorst 2014-08-16
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.