2012-12-22 3 views
2

그래서 내가 뭘하려고 문자열 목록 구문 분석하는 것입니다 : 내가 DDD의 내용물을이상한 오류 부스트 :: 정신 :: position_iterator2는

namespace qi = boost::spirit::qi; 
namespace ascii = boost::spirit::ascii; 

std::string TEST = "aa\nbbbb\nccc\n"; 

std::istringstream INPUT (TEST); 
std::noskipws(INPUT); 

typedef std::istreambuf_iterator<char> base_iterator; 
typedef boost::spirit::multi_pass<base_iterator> multi_pass_iter; 
typedef boost::spirit::classic::position_iterator2<multi_pass_iter> pos_iterator; 

base_iterator base_begin(INPUT); 

multi_pass_iter first = boost::spirit::make_default_multi_pass(base_begin); 
multi_pass_iter last; 

pos_iterator pfirst(first,last,std::string("DD")); 
pos_iterator plast; 

using qi::lexeme; 
using ascii::alpha; 

std::vector<std::string> DDD; 
bool res = qi::phrase_parse(pfirst,plast,* lexeme[+alpha],ascii::space,DDD); 

for (const auto & d : DDD) std::cout << d << " (" << d.size() << ")" << std::endl; 

가 올바른 크기의 3 문자열을하지만, 모든 공백의.

는 경우 대신 내가 예상대로

bool res = qi::phrase_parse(first,last,* lexeme[+alpha],ascii::space,DDD); 

모든 작품 사용합니다. 과거에 아무런 문제없이 position_iterator2을 사용 했으므로 버그라고 생각하지 않습니다. 내가 놓친 게 있니?

+0

문자열을 분할하는 데 정말로 boost :: spirit이 필요합니까? – maverik

+2

@maverik 방금 더 큰 프로젝트에서 문제를 격리했습니다. – sbabbi

+0

'for'는 함수 밖에서 유효하지 않습니다. –

답변

1

예 : here이 작동하지 않습니다.

boost/iterator/iterator_adaptor.hpp(306): warning C4172: returning address of local variable or temporary 
boost_1_52_0\boost/iterator/iterator_adaptor.hpp(306) : while compiling class template member function 'const char &boost::iterator_adaptor<Derived,Base,Value,Traversal>::dereference(void) const' 
     with 
     [ 
      Derived=boost::spirit::classic::position_iterator2<forward_iterator_type>, 
      Base=forward_iterator_type, 
      Value=const char, 
      Traversal=boost::forward_traversal_tag 
     ] 

"일시적으로 역 참조 iterator_adaptor"의 빠른 구글 검색 iterator_adaptorReference 매개 변수가 아닌 참조 형식이 될 것을 권장합니다 this에 이르게 : 비주얼 스튜디오 2012 사용 모두 경고를 제공합니다.

"boost/spirit/home/classic/iterator/impl/position_iterator.ipp"파일을 변경해야합니다.

typedef boost::iterator_adaptor< 
    main_iter_t, 
    ForwardIterT, 
    const_value_type, 
    boost::forward_traversal_tag 
> type; 

에 : 특히 당신은 변경해야 할 것

typedef boost::iterator_adaptor< 
    main_iter_t, 
    ForwardIterT, 
    const_value_type, 
    boost::forward_traversal_tag, 
    const_value_type 
> type; 

이 새로운 오류로 리드를 모두 g ++ 및 VC11 : 당신이 변경하면 피할 수

boost_1_52_0\boost/concept_check.hpp(212): error C2440: 'initializing' : cannot convert from 'boost::detail::iterator_category_with_traversal<Category,Traversal>' to 'std::forward_iterator_tag' 
      with 
      [ 
       Category=std::input_iterator_tag, 
       Traversal=boost::forward_traversal_tag 
      ] 
      No constructor could take the source type, or constructor overload resolution was ambiguous 

iterator_adaptor typedef에 :

typedef boost::iterator_adaptor< 
    main_iter_t, 
    ForwardIterT, 
    const_value_type, 
    std::forward_iterator_tag, 
    const_value_type 
> type; 

이렇게하면 (코드에 기반한) 아래 프로그램과 boost-spirit.com의 예제가 모두 작동하지만, 다른 경우에는 손상되지 않을 것이라는 확신이 들지 않으므로 재량에 따라 사용하십시오.

#include <vector> 
#include <istream> 
#include <sstream> 
#include <iostream> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/support_multi_pass.hpp> 
#include <boost/spirit/include/classic_position_iterator.hpp> 

namespace qi = boost::spirit::qi; 
namespace ascii = boost::spirit::ascii; 

int main() 
{ 

    std::string TEST = "aa\nbbbb\nccc\n"; 

    std::istringstream INPUT (TEST); 
    std::noskipws(INPUT); 

    typedef std::istreambuf_iterator<char> base_iterator; 
    typedef boost::spirit::multi_pass<base_iterator> multi_pass_iter; 
    typedef boost::spirit::classic::position_iterator2<multi_pass_iter> pos_iterator; 

    base_iterator base_begin(INPUT); 

    multi_pass_iter first = boost::spirit::make_default_multi_pass(base_begin); 
    multi_pass_iter last; 

    pos_iterator pfirst(first,last,std::string("DD")); 
    pos_iterator plast; 

    using qi::lexeme; 
    using ascii::alpha; 

    std::vector<std::string> DDD; 
    bool res = qi::phrase_parse(pfirst,plast,* lexeme[+alpha],ascii::space,DDD); 

    if(res && pfirst==plast) 
    { 
     for (const auto & d : DDD) 
      std::cout << d << " (" << d.size() << ")" << std::endl; 
    } 
    else 
    { 
     std::cout << "Parsing error." << std::endl; 
    } 

    return 0; 
} 
+0

고맙습니다. 시도해 보겠습니다. (버그보고) – sbabbi

2

나는 이것이 a Spirit bug이라고 생각합니다. ticket의 맨 아래를 보면 패치를 찾을 수 있다고 생각하는 패치를 찾을 수 있습니다.

+0

"i.c.m. VC++? " –

+0

데이브에게 감사 드려요. 여기에 관련 추가 사항이 있습니다. (VC++과 실제로 결합되어 있는지 궁금합니다.) – sehe