나는 안전 부울 관용구를 제공하는 일반적으로 받아 들여지는 유틸리티 라이브러리 모르겠어요. Boost에는 몇 가지 시도가 있었으며, 종종 안전한 bool 구현 (이름 지정 규칙, 매크로, 인라인 포함, 상속)을 제공하는 방법에 대한 논쟁이 종종있었습니다. 결과적으로, Boost에는 적어도 세 가지 구현이 있으며, 하나의 구현 인 외부 용도로만 설계된 Boost.Spirit.Classic's safe_bool이 있습니다. 각 구현을위한
세부 사항 및 개념 : 그래서 명시 적 외부 사용을 위해 설계되지 세부 디렉토리에 포함 된
- Boost.Range's safe_bool
- .
- 템플릿 도우미 유형과 정적 멤버 함수를 사용하여 구현됩니다.
- 안전한 - 부울 활성화 클래스 것으로 예상된다 :
- 는
operator boost::range_detail::safe_bool<MemberPtr>::unspecified_bool_type() const
멤버 함수를 제공하는 정적 safe_bool::to_unspecified_bool()
기능에 위임한다.
- Boost.SmartPtr's operator_bool
:
- 에서, 세부 디렉토리에 포함 된이 이렇게 명시 적으로 외부 사용을 위해 설계되지 않았습니다.
- 는 헤더 파일은 클래스 정의 내에 직접 포함하기위한 것입니다. 예를 들어 shared_ptr.hpp을 참조하십시오.
smart_ptr/detail/operator.hpp
을 포함하기 전에 boost/detail/workaround.hpp
이 필요합니다.
- 이
this_type
유형을 제공 :
- 은 주변 안전 부울 활성화 클래스 것으로 예상된다.
T
유형을 입력하십시오.
T* px
멤버 변수를 제공하십시오.
외부 사용하도록 설계
- Boost.Spirit.Classic's safe_bool
.
- CRTP 패턴을 사용합니다.
- 기본 클래스 체인을 지원하도록 설계되었으므로
boost::spirit::class::safe_bool
을 파생 클래스에서 다중 상속없이 사용하도록 허용합니다.
- 안전한 - 부울 활성화 클래스 것으로 예상된다 :
- 는 공개적으로
boost::spirit::classic::safe_bool<Derived>
에서 파생. Derived
이 이미 Base
에서 상속 된 경우 boost::spirit::classic::safe_bool< Derived, Base >
을 사용합니다.
bool operator_bool() const
멤버 함수를 제공하십시오.
는
이 예는 1.50 부스트 사용합니다.
// Safe-bool idiom with Boost.Range.
#include <boost/range/detail/safe_bool.hpp>
class range_bool
{
public:
range_bool(int x) : x_(x) {}
private:
// None of these are required, but makes the implementation cleaner.
typedef boost::range_detail::safe_bool< int range_bool::* > safe_bool_t;
typedef safe_bool_t::unspecified_bool_type unspecified_bool_type;
int dummy;
public:
operator unspecified_bool_type() const
{
return safe_bool_t::to_unspecified_bool(x_ > 0, &range_bool::dummy);
}
private:
int x_;
};
// Safe-bool idiom with Boost.SmartPtr.
#include <boost/detail/workaround.hpp>
class smart_ptr_bool
{
public:
smart_ptr_bool(int x) { px = (x > 0) ? &dummy : 0 ; }
private:
typedef smart_ptr_bool this_type; // -.
typedef int T; // :- Required concepts when using
T* px; // -' smart_ptr's operator_bool.
private:
T dummy; // Simple helper.
public:
#include <boost/smart_ptr/detail/operator_bool.hpp>
};
// Safe-bool idiom with Boost.Spirit.
#include <boost/spirit/include/classic_safe_bool.hpp>
class spirit_bool: public boost::spirit::classic::safe_bool<spirit_bool>
{
public:
spirit_bool(int x) : x_(x) {}
public:
// bool operator_bool() is required by the spirit's safe_bool CRTP.
bool operator_bool() const { return x_ > 0; }
private:
int x_;
};
#include <iostream>
int main()
{
std::cout << "range_bool(-1): " << range_bool(-1) << std::endl
<< "range_bool( 1): " << range_bool( 1) << std::endl
<< "smart_ptr_bool(-1): " << smart_ptr_bool(-1) << std::endl
<< "smart_ptr_bool( 1): " << smart_ptr_bool( 1) << std::endl
<< "spirit_bool(-1): " << spirit_bool(-1) << std::endl
<< "spirit_bool( 1): " << spirit_bool( 1) << std::endl;
return 0;
}
결과 출력 :
range_bool(-1): 0
range_bool( 1): 1
smart_ptr_bool(-1): 0
smart_ptr_bool( 1): 1
spirit_bool(-1): 0
spirit_bool( 1): 1
내가 어떤 대안 모르겠어요 생성자에 전달 된 정수가 0보다 큰 경우 각 클래스는 부울 컨텍스트에서 true로 평가해야합니다. safe-bool 관용구를 가로 질렀을 때 대부분의 구현은 Bjorn Karlsson's article에 제공된 구현의 복사하여 붙여 넣기 변형입니다.
암시 적으로 'bool'로 변환하지 않아도 문제를 해결할 생각이십니까? –
이 기사의 3 페이지에 재사용 가능한 Safe Bool 구현이 있습니다. http://www.artima.com/cppsource/safebool.html –
감사합니다. 나는 언급하지 않았지만 나는 그것을 보았고 그 코드를 복사하여 붙여 넣을 수도 있었지만, 공통적으로 받아 들여지고 유지 관리되는 유틸리티 라이브러리 (boost가 염두에 두었다)가 이미 그렇게하기를 희망했다. – CygnusX1