2016-07-04 2 views
1

부스트 정신, 피닉스와 융합 라이브러리를 사용하는 방법을 학습하는 동안, 나는 MSVC (2015 년 버전 14)에 컴파일하고 밀어하지 않습니다이 최소한의 예를 건너 온 1.61.0캐스팅 속성 :: 변형

#include <boost/spirit/include/karma.hpp> 
#include <boost/variant/variant.hpp> 

namespace ka = boost::spirit::karma; 

struct U /* a kind of union (legacy code)*/ 
    { 
     bool kind; 
     double foo; /* if kind = true */ 
     size_t bar; /* if kind = false */ 
    }; 

typedef boost::variant<double, size_t> UVariant; 

namespace boost { namespace spirit { namespace traits { 
    template<> 
    struct transform_attribute<U,UVariant,ka::domain> 
    { 
     typedef UVariant type; 
     static type pre(U & u) { 
      switch (u.kind) 
      { 
      case true: 
       return type(u.foo); 
      case false: 
       return type(u.bar); 
      } 
     } 
    }; 
}}} 

typedef std::back_insert_iterator<std::string> iterator; 

class grm: public ka::grammar<iterator, U()> 
{ 
public: 
    grm():grm::base_type(start) 
    { 
     start = ka::attr_cast<U,UVariant >(foo | bar); 
     foo = ka::double_; 
     bar = ka::uint_; 
     */ 
    } 
private: 
    ka::rule<iterator,U()> start; 
    ka::rule<iterator,double()> foo; 
    ka::rule<iterator,size_t()> bar; 
}; 

int main(int argc, char * argv[]) 
{ 
    grm g; 
    U u; 
    u.kind = true; 
    u.foo = 1.0; 

    std::string generated; 
    std::back_insert_iterator<std::string> sink(generated); 
    ka::generate(sink,g,u); 


    return 0; 
} 

오류 C2665 : '부스트 :: 자세히 :: 변형 :: make_initializer_node :: 적용 :: initializer_node : 초기화'

은 그 때 나는 다음과 같은 오류 메시지가 얻을 5 오버로드 없음을 수 모든 인수 유형 변환

대답이 문제를 해결하는 방법과 모든 유형이 올바르게 제공되었는지 (유형 변환 필요 없음) 실제로 문제인지 여부는 알 수 없지만 비슷한 문제가 here으로보고되었습니다.

답변

1

Spirit이 사용자 지정 사용자 지정 지점을 선택하지 않는 것 같습니다. 그것은 기본 하나를 사용하고 있으며, const U (0120)에서 boost::variant<double,size_t>을 생성하려고 시도하는데 분명히 실패합니다.

namespace boost { namespace spirit { namespace traits { 
    template<> 
    struct transform_attribute<const U,UVariant,ka::domain> 
           ^^^^^^^ 
    { 
     typedef UVariant type; 
     static type pre(const U & u) { 
         ^^^^^^^ 
      //same as before 
     } 
    }; 
}}} 

후는 카르마에 의해 포착되고 모든 것이 작동합니다 : 당신이 transform_attribute의 전문화를 변경해야하므로

카르마는 항상 내부에서 const를 값으로 작동합니다.

전체 샘플 (On rextester) :

#include <boost/spirit/include/karma.hpp> 
#include <boost/variant/variant.hpp> 

namespace ka = boost::spirit::karma; 

struct U /* a kind of union (legacy code)*/ 
    { 
     bool kind; 
     double foo; /* if kind = true */ 
     size_t bar; /* if kind = false */ 
    }; 

typedef boost::variant<double, size_t> UVariant; 

namespace boost { namespace spirit { namespace traits { 
    template<> 
    struct transform_attribute<const U,UVariant,ka::domain> 
    { 
     typedef UVariant type; 
     static type pre(const U & u) { 
      if(u.kind) 
      { 
       return type(u.foo); 
      } 
      else 
      { 
       return type(u.bar); 
      } 
     } 
    }; 
}}} 

typedef std::back_insert_iterator<std::string> iterator; 

class grm: public ka::grammar<iterator, U()> 
{ 
public: 
    grm():grm::base_type(start) 
    { 
     start = ka::attr_cast<UVariant>(foo | bar); 
     foo = ka::double_; 
     bar = ka::uint_; 
    } 
private: 
    ka::rule<iterator,U()> start; 
    ka::rule<iterator,double()> foo; 
    ka::rule<iterator,size_t()> bar; 
}; 

int main(int argc, char * argv[]) 
{ 
    grm g; 
    U u; 
    u.kind = false; 
    u.foo = 1.0; 
    u.bar = 34; 

    std::string generated; 
    std::back_insert_iterator<std::string> sink(generated); 
    ka::generate(sink,g,u); 

    std::cout << generated << std::endl; 


    return 0; 
} 
+0

그것은 일을, 당신을 감사합니다. 경험으로 알았거나 컴파일러의 x ko 오류 메시지를 면밀히 조사 했습니까? – Heyji

+0

Clang의 오류 메시지는 매우 명확하며 그 점이 나를 도왔습니다. 정확한 오류 :'멤버 함수의 인스턴스 생성 'boost :: spirit :: karma :: transform_attribute , void> :: pre'requested '. – llonesmiz