2012-07-30 7 views
4

에서 변형 기본 유형 I은 S-expression이 모델 재귀 변형이있다. 그러나, 나는 push_back() 방문자의 구현과 붙어있어.변경 부스트 :: 방문자

struct push_back_visitor: public boost::static_visitor<void> 
    { 
     push_back_visitor(const sexpr &arg): arg_(arg) {} 

     template <typename T> 
     void operator()(const T &value) const { 
     throw bad_visit(); 
     } 

     void operator()(nil &val) const { 
     // how to change the underlying type to list<sexpr> here? 
     // lst.push_back(arg_); 
     } 

     void operator()(list<sexpr> &lst) const { 
     lst.push_back(arg_); 
     } 

     sexpr arg_; 
    }; 

모든 아이디어 : 기본 유형 nil을 때, 나는 그것이 list<sexpr>에 해당 유형을 변경하고 공급 된 값을 다시 밀어 싶습니다?

+0

정말 컴파일 될까요? 유형 자체를 정의하는 동안'sexpr' 유형을 사용하고 있습니다. –

+0

나는 단지 내 요점을 설명하기 위해 코드를 최소화하려고했습니다. 내가 실제로 가지고있는 것을 보여주기 위해 코드를 편집했습니다. 이것은 여전히 ​​최소화됩니다. sexpr은 기본 재귀 변형 ('node')에 apply_visitor() 요청을 전달하는 node_type에 대한 래퍼로 생각할 수 있습니다. –

답변

3

boost::variant은 방문자 내에서 변형에 액세스하는 메커니즘을 제공하지 않습니다. 그러나 변형 자체에 대한 참조를 전달하기 위해 방문자를 수정하거나 줄 바꿈하는 것을 막을 수있는 방법은 없습니다. 해당 variant를 방문하는 방문자 내에서 variant 유형을 수정하는 것은 설명서에 언급되어 있지 않지만 안전해야한다고 생각됩니다 (변형 된 방문자 적용 함수는 방문자가 호출되는 즉시 반환해야하기 때문에).

template<typename Variant, typename Visitor> 
struct carry_variant_visitor 
    : public boost::static_visitor<typename Visitor::result_type> 
{ 
    carry_variant_visitor(Variant &variant, Visitor visitor): 
     variant_(variant), visitor_(visitor) { } 
    template<typename T> 
    typename Visitor::result_type operator()(T &t) const { 
     return visitor_(variant_, t); 
    } 
    Variant &variant_; 
    Visitor visitor_; 
} 
+0

차가움. 힌트를 가져 주셔서 감사합니다! –

+0

저는 대개 노드를 복사하거나 수정 된 객체를 반환하는 변형 방문자를 만듭니다. 비효율적 일 수 있지만 표현력과 유지 보수성이 우선입니다. 당신이 그들을 가지고 있음을 증명할 때 perf 문제를 해결하십시오 (이 경우 논리를 다시 쓰거나 변형을 사용하지 않을 수도 있습니다) – sehe