2012-09-10 3 views
2

Value이라는 내 클래스에서 문자열을 생성하려고하는데 boost::spirit::karma을 사용했지만이 문제가 발생했습니다. 내 문제를 간단한 예제로 추출하려고했습니다.boost :: spirit :: karma 조건을 사용하여 대체 연산자 (|) 사용

int main() 
{ 
    using karma::bool_; 
    using karma::double_; 
    using karma::rule; 
    using karma::eps; 

    std::string generated; 
    std::back_insert_iterator<std::string> sink(generated); 

    rule<std::back_insert_iterator<std::string>, Value()> value_rule = bool_ | double_; 

    Value bool_value = Value(true); 
    Value double_value = Value(5.0); 

    karma::generate(sink, value_rule, bool_value); 
    std::cout << generated << "\n"; 

    generated.clear(); 

    karma::generate(sink, value_rule, double_value); 
    std::cout << generated << "\n"; 

    return 0; 
} 

첫 번째 호출 karma::generate()을에 :

여기
class Value 
{ 
public: 

    enum ValueType 
    { 
     BoolType, 
     NumericType 
    }; 

    Value(bool b) : type_(BoolType), value_(b) {} 
    Value(const double d) : type_(NumericType), value_(d) {}; 

    ValueType type() { return type_; } 

    operator bool() { return boost::get<bool>(value_); } 
    operator double() { return boost::get<double>(value_); } 

private: 
    ValueType type_; 
    boost::variant<bool, double> value_; 

}; 

당신이 내가 할 묶는 무슨을 볼 수 있습니다

나는 다음과 같은 클래스의 인스턴스에서 카르마 문자열을 생성 할 값이 bool이고 규칙의 첫 번째 생성자가 bool을 "소비"하기 때문에 정상적으로 작동합니다. 그러나 두 번째 karma::generate()boost::bad_get으로 실패합니다. 왜냐하면 카르마는 부울을 먹기 때문에 Value::operator bool()을 호출하기 때문입니다.

나의 다음 생각은 내 생성 규칙을 수정하고 조건과 함께 eps() 생성기를 사용했지만, 여기에 내가 붙어있어 :

value_rule = (eps(...) << bool_) | (eps(...) << double_); 

나는 STH와 EPS 발생기의 브래킷을 채워 드릴 수 없습니다. 이 같은 (물론 작동하지) : 나는 boost::phoenix에 가려고했지만, 내 뇌가 이런 것들에 대한 준비를하지 않는 것 같다

eps(value.type() == BoolType) 

.

도와주세요! 입니다 마음에 오는 main.cpp

답변

3

간단한 일이 : (변종 카르마에 의해 아주 잘 지원되지대로) value_ 변형을 사용

여기 내 전체 예 (컴파일하지만 작동하지 않습니다)입니다. 이 value_ (예를 들어 에 친구)을 노출 필요하지만

rule<std::back_insert_iterator<std::string>, Value()> value_rule; 

value_rule = (bool_ | double_) 
    [ _1 = phx::bind(&Value::value_, _val) ]; 

을 그래서 당신은 접근 방법을 선호 할 수 있습니다 의미 조치 내부 피닉스 바인딩을 사용하여

작동합니다. 여기

는 작업 예를 http://liveworkspace.org/code/22ab2093ad9bd3b03e55a7f3dde952f8

입니다
#include <boost/spirit/include/karma.hpp> 
#include <boost/spirit/include/phoenix.hpp> 
#include <boost/variant.hpp> 

#include <iostream> 
#include <string> 

namespace karma = boost::spirit::karma; 
namespace phx = boost::phoenix; 

class Value 
{ 
public: 

    enum ValueType 
    { 
     BoolType, 
     NumericType 
    }; 

    Value(bool b) : type_(BoolType), value_(b) {} 
    Value(double d) : type_(NumericType), value_(d) {}; 

    ValueType type() { return type_; } 

    operator bool() { return boost::get<bool>(value_); } 
    operator double() { return boost::get<double>(value_); } 

    private: 
    ValueType type_; 

    friend int main(); 
    boost::variant<bool, double> value_; 
}; 

namespace karma = boost::spirit::karma; 

int main() 
{ 
    using namespace karma; 
    std::string generated; 
    std::back_insert_iterator<std::string> sink(generated); 

    rule<std::back_insert_iterator<std::string>, Value()> value_rule; 

    value_rule = (bool_ | double_) 
     [ _1 = phx::bind(&Value::value_, _val) ]; 

    Value bool_value = Value(true); 
    Value double_value = Value(5.0); 

    karma::generate(sink, value_rule, bool_value); 
    std::cout << generated << "\n"; 

    generated.clear(); 
    karma::generate(sink, value_rule, double_value); 
    std::cout << generated << "\n"; 

    return 0; 
} 

출력

true 
5.0 

끄기 - 주제 : 나는 (적어도에서) 변환 사업자explicit을 표시하는 것이 좋습니다 수, 방지하기 위해 불쾌한 놀라움?

관련 문제