2012-08-02 4 views
13

부스트 라이브러리가 안전한 부울 관용구의 구현을 제공하여 클래스를 파생시킬 수 있습니까? 예부울에 안전한 부울 관용구?

경우 - 그것은 어디?

만약 어떤 - 그것을 자신을 구현 넘어 내 대안이 무엇입니까?


나는 다음과 같은 비슷한 질문을 발견 : " Is there a safe bool idiom helper in boost?을"및 허용 대답은 Boost.Operatorsbool_testable<>를 사용하여 제안합니다. 나는 boost manual을 선택한 경우

불행히도, 난 거기를 찾을 수 없습니다. 그것을 사용하는 코드도 컴파일에 실패합니다.

또 다른 질문에 "Was boost::bool_testable<> relocated or removed?"이 나타났습니다. 거기에있는 댓글은 실제로 bool_testable이 어떤 부스트 버전의 버전도 만들지 않았다고 제안합니다.

또한 내 프로젝트에 복사 - 붙여 넣기 할 수있는 코드를 포함하는 주제에 article by Bjorn Karlsson 흥미로운 있습니다. 그러나 이미 구현되어있는 일반적으로 인정되고 유지 관리되는 유틸리티 라이브러리 (예 : 부스트)가 있기를 바라고 있습니다.


호환성을 이유로 C++ 11에 의존하고 싶지 않습니다.

+3

암시 적으로 'bool'로 변환하지 않아도 문제를 해결할 생각이십니까? –

+2

이 기사의 3 페이지에 재사용 가능한 Safe Bool 구현이 있습니다. http://www.artima.com/cppsource/safebool.html –

+0

감사합니다. 나는 언급하지 않았지만 나는 그것을 보았고 그 코드를 복사하여 붙여 넣을 수도 있었지만, 공통적으로 받아 들여지고 유지 관리되는 유틸리티 라이브러리 (boost가 염두에 두었다)가 이미 그렇게하기를 희망했다. – CygnusX1

답변

15

나는 안전 부울 관용구를 제공하는 일반적으로 받아 들여지는 유틸리티 라이브러리 모르겠어요. 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에 제공된 구현의 복사하여 붙여 넣기 변형입니다.