2013-09-02 2 views
3

빈과 3 개의 요소 사이의 크기를 가질 수있는 입력 벡터가 있습니다. 생성 된 문자열을 항상 공백으로 구분 된 3 개의 부동 소수점으로 사용하려면 벡터에 요소가 충분하지 않은 경우 기본값이 사용됩니다.아무 것도 발견되지 않을 때 기본값 생성

#include <iostream> 
#include <iterator> 
#include <vector> 

#include "boost/spirit/include/karma.hpp" 

namespace karma = boost::spirit::karma; 
namespace phx = boost::phoenix; 
typedef std::back_insert_iterator<std::string> BackInsertIt; 

int main(int argc, char* argv[]) 
{ 
    std::vector<float> input; 
    input.push_back(1.0f); 
    input.push_back(2.0f); 

    struct TestGram 
     : karma::grammar<BackInsertIt, std::vector<float>(), karma::space_type> 
    { 
     TestGram() : TestGram::base_type(output) 
     { 
      using namespace karma; 
      floatRule = double_; 

      output = repeat(3)[ floatRule ]; 
     } 

     karma::rule<BackInsertIt, std::vector<float>(), karma::space_type> output; 
     karma::rule<BackInsertIt, float(), karma::space_type> floatRule; 
    } testGram; 


    std::string output; 
    BackInsertIt sink(output); 
    karma::generate_delimited(sink, testGram, karma::space, input); 

    std::cout << "Generated: " << output << std::endl; 

    std::cout << "Press enter to exit" << std::endl; 
    std::cin.get(); 
    return 0; 
} 

나는 이런 일에 플로트 규칙을 수정하려고했습니다 : floatRule = double_ | lit(0.0f)를, 그러나 그것은 단지 나에게 컴파일 오류를 준 지금까지 나는 벡터의 내용 만 출력 관리했습니다. 비슷한 다른 많은 것들에 대해서도 마찬가지입니다.

이 작업을 수행하는 방법을 알지 못합니다. 어떤 도움은 위대한 것입니다 :)

편집 : 그냥 명확하게. 2 개의 요소 (1.0과 2.0)를 포함한 벡터를 가지고 있다면, 다음과 같은 문자열을 생성하고 싶습니다 : "1.0 2.0 0.0" (마지막 값은 기본값이어야합니다).

답변

2

꽤하지 않습니다,하지만 작업 :

#include <iostream> 
#include <iterator> 
#include <vector> 
#define BOOST_SPIRIT_USE_PHOENIX_V3 
#include "boost/spirit/include/karma.hpp" 
#include <boost/spirit/include/phoenix.hpp> 

namespace karma = boost::spirit::karma; 
namespace phx = boost::phoenix; 
typedef std::back_insert_iterator<std::string> BackInsertIt; 

int main(int argc, char* argv[]) { 
    std::vector<float> input; 
    input.push_back(1.0f); 
    input.push_back(2.0f); 

    struct TestGram: karma::grammar<BackInsertIt, std::vector<float>(), 
     karma::space_type> { 
    TestGram() 
     : TestGram::base_type(output) { 
     using namespace karma; 
     floatRule = double_; 

     output = repeat(phx::bind(&std::vector<float>::size, (karma::_val)))[floatRule] 
      << repeat(3 - phx::bind(&std::vector<float>::size, (karma::_val)))[karma::lit("0.0")]; 
    } 

    karma::rule<BackInsertIt, std::vector<float>(), karma::space_type> output; 
    karma::rule<BackInsertIt, float(), karma::space_type> floatRule; 
    } testGram; 

    std::string output; 
    BackInsertIt sink(output); 
    karma::generate_delimited(sink, testGram, karma::space, input); 

    std::cout << "Generated: " << output << std::endl; 

    return 0; 
} 
+0

예. 고마워요. – Krienie

+0

좀 더 맛있는 것을 생각해 냈습니다. 그러나, 나는 당신의 데이터 타입이 아마도'struct Vec3 {float a, b; 선택 사항 c; }; ' – sehe

+1

@sehe 데이터 유형을 변경하지 않을 것입니다. 왜냐하면 이것은 사용되는 컨텍스트 때문입니다. 만약 그렇다면, 나는 파이프 라인의 거의 절반을 변경해야합니다. – Krienie

1

큰 경고 :

표시된 코드가 결함이 전파 속성 중 버그로 인해, 또는 때문에 카르마의 남용에 (주석 참조).

입력 벡터에서 이터레이터 end() 반복자를 참조 해제하는 미확인 동작 (아마도)을 호출합니다.

floatRule는 대신 optional<float>을 받아 들여야한다,

floatRule = double_ | "0.0"; 

    output = -floatRule << -floatRule << -floatRule; 

주를 작동합니다. 이 Live on Coliru

최소한의 예를 참조하십시오 : 속임수를 썼는지

#include "boost/spirit/include/karma.hpp" 

namespace karma = boost::spirit::karma; 
using It = boost::spirit::ostream_iterator; 

int main(int argc, char* argv[]) 
{ 
    const std::vector<float> input { 1.0f, 2.0f }; 

    using namespace karma; 
    rule<It, boost::optional<float>()> floatRule  = double_ | "0.0"; 
    rule<It, std::vector<float>(), space_type> output = -floatRule << -floatRule << -floatRule; 

    std::cout << format_delimited(output, space, input); 
} 

+0

VS2012가 불행히도 귀하의 솔루션을 좋아하지 않습니다. . 나는 보안 경고를 받는다. (이것은 내가 -D_SCL_SECURE_NO_WARNINGS를 설정하여 컴파일 할 수 없도록 만들지 만, 그렇게하지 않으면 어떤 다른 버그가 나올지 알지 못한다.) 'error C4996 : 'std :: _ Copy_impl': 안전하지 않은 매개 변수를 가진 함수 호출' – Krienie

+0

이것은 iterator를 함수/사용하지 않는 checked (SCARY?) 반복자로 정적으로 검사 할 수 없다는 것을 의미합니다. 그것은 벡터 반복자 일 수도 있고, 가능하다면''0.0 "'(lit ("0.0 ")으로 시도해도 좋을까요? 아니면 DEBUG 빌드를 비활성화하십시오.) (MSVC가 없습니다) – sehe

+0

DEBUG 빌드를 비활성화하면 컴파일하지만 출력은 3 개의 부동 소수점 대신 웃는 얼굴입니다. (예 : 농담이 아닙니다.) 예제를 코드에 적용하는 동안 다른 부분을 잘못했을 수도 있지만 문제가되지 않습니다. 마이크의 "못생긴 "코드. 어쨌든 노력해 주셔서 감사합니다.) – Krienie

관련 문제