2015-10-12 13 views
5

के लिए विशेषता के रूप में std :: array का उपयोग करके मैं बूस्ट :: भावना की नवीनतम रिलीज x3 (जैसा कि बूस्ट 1.54 में शामिल है) का उपयोग करके निश्चित आकार std::array कंटेनर में संख्याओं की एक सूची को पार्स करने का प्रयास कर रहा हूं। std::array के बाद से आवश्यक कार्य हैं, यह एक कंटेनर के रूप में पहचाना जाता है, लेकिन इसमें सम्मिलित फ़ंक्शन की कमी है जो इसे असंगत बनाता है।बूस्ट :: भावना :: x3

#include <boost/spirit/home/x3.hpp> 

#include <array> 
#include <iostream> 
#include <string> 

namespace x3 = boost::spirit::x3; 
namespace ascii = boost::spirit::x3::ascii; 

typedef std::array<double, 3> Vertex; 

int main(int, char**) { 
    using x3::double_; 
    using ascii::blank; 

    std::string input = "3.1415 42 23.5"; 
    auto iter = input.begin(); 

    auto vertex = x3::rule<class vertex, Vertex>{} = 
    double_ >> double_ >> double_; 

    Vertex v; 

    bool const res = x3::phrase_parse(iter, input.end(), vertex, blank, v); 
    if (!res || iter != input.end()) return EXIT_FAILURE; 

    std::cout << "Match:" << std::endl; 
    for (auto vi : v) std::cout << vi << std::endl; 
    return EXIT_SUCCESS; 
} 

यह संकलन नहीं करेगा क्योंकि std::array कोई insert कार्य है: यहाँ मैं क्या हासिल करने की कोशिश कर रहा हूँ की एक छोटी सी उदाहरण है। समाधान के लिए मैं अर्थ कार्यों के लिए इस्तेमाल किया:

auto vertex() { 
    using namespace x3; 
    return rule<class vertex_id, Vertex>{} = 
    double_[([](auto &c) { _val(c)[0] = _attr(c); })] >> 
    double_[([](auto &c) { _val(c)[1] = _attr(c); })] >> 
    double_[([](auto &c) { _val(c)[2] = _attr(c); })]; 
} 

और फिर

x3::phrase_parse(iter, input.end(), vertex(), blank, v); 

फोन के बजाय। यह काम करता है (clang 3.6.0 -std = C++ 14 के साथ), लेकिन मुझे लगता है कि यह समाधान बहुत ही सुरुचिपूर्ण और पढ़ने में मुश्किल है।

BOOST_FUSION_ADAPT_ADT(
    Vertex, 
    (double, double, obj[0], obj[0] = val) 
    (double, double, obj[1], obj[1] = val) 
    (double, double, obj[2], obj[2] = val)) 

और फिर वर्टेक्स के लिए x3::traits::is_container विशेषज्ञता x3 बताने के लिए एक कंटेनर के रूप में std :: सरणी इलाज नहीं करने के लिए:

तो मैं एक संलयन अनुक्रम BOOST_FUSION_ADAPT_ADT इसलिए की तरह का उपयोग कर के रूप में std :: सरणी अनुकूलन करने की कोशिश की

namespace boost { namespace spirit { namespace x3 { namespace traits { 
    template<> struct is_container<Vertex> : public mpl::false_ {}; 
}}}} 

लेकिन यह x3 के साथ संयोजन में संकलित नहीं होगा। क्या यह एक बग है या क्या मैं इसे गलत इस्तेमाल कर रहा हूं? कॉलिंग उदा। fusion::front(v) सभी x3 कोड संकलित और काम किए बिना, तो मुझे लगता है कि मेरा कोड पूरी तरह से गलत नहीं है।

हालांकि मुझे यकीन है कि x3 के साथ एक क्लीनर समाधान है जिसमें इस साधारण समस्या के लिए कोई संलयन एडेप्टर या अर्थपूर्ण क्रिया शामिल नहीं है।

+0

क्या 'बूस्ट :: सरणी' विकल्प है? मेरा मानना ​​है कि "बूस्ट/फ़्यूज़न/शामिल/बूस्ट_एरेआरएचपीपी" 'डबल_ >> डबल_ >> डबल_' काम करना चाहिए। – llonesmiz

+0

मैंने उन बेवकूफ त्रुटियों को ठीक किया, इसके लिए खेद है। 'boost :: array' एक विकल्प नहीं है क्योंकि मैं मौजूदा कोड को इंटरफ़ेस कर रहा हूं जो' std :: array' पर भारी निर्भर करता है। – ithron

+0

[यह एक भयानक हैक] (http://coliru.stacked-crooked.com/a/412c97fecfa4e4b1) अपना दृष्टिकोण संकलित करने के लिए। आपको शायद एक बेहतर उत्तर (या वास्तव में एक अच्छा) के लिए इंतजार करना चाहिए। – llonesmiz

उत्तर

0

आपके द्वारा पोस्ट किया गया कोड मैला त्रुटियों के साथ riddled है। वास्तव में संकलन करने के लिए वहां कुछ भी उम्मीद करने की कोई वजह नहीं है।

भले ही, मैंने इसे साफ़ किया। बेशक आपको

#include <boost/fusion/adapted/array.hpp> 

दुख की बात है कि यह बस काम नहीं करता है। मैं काफी हद तक एक ही निष्कर्ष तक पहुंच गया (जैसा कि आप उल्लेख करते हैं, उसी चीज को आजमाने के बाद, :) :)।

यह आत्मा एक्स 3 के साथ उपयोगिता मुद्दा है - जो अभी भी प्रयोगात्मक चरण में है। आप इसे [भावना-सामान्य] मेलिंग सूची में रिपोर्ट कर सकते हैं। प्रतिक्रिया आमतौर पर बहुत तेज़ है। मामले में आप को देखने के लिए कि मैं क्या http://paste.ubuntu.com/12764268/ के साथ काम किया चाहते


¹; मैंने तुलना के लिए x3::repeat(3)[x3::double_] भी उपयोग किया है।

+0

दुर्भाग्यवश 'std :: array' को संलयन द्वारा अनुकूलित नहीं किया गया है। आपके द्वारा सुझाए गए शीर्षलेख (या "बूस्ट/फ़्यूज़न/शामिल/boost_array.hpp") केवल 'boost :: array' को प्रभावित करता है। [यह] (http://coliru.stacked-crooked.com/a/07416373f7d19da3) कुछ छोटे बदलावों के साथ काम करता प्रतीत होता है। [यहां] (https://svn.boost.org/trac/boost/ticket/8241) 'std :: array' को अनुकूलित करने का एक बहुत पुराना प्रयास है (मुझे अभी पता नहीं है कि यह अभी भी काम करता है)। – llonesmiz

+0

हू। यह मेरे लिए या तो बूस्ट सरणी के लायक काम नहीं करता था। जब मेरे पास समय है तो मतभेद देखेंगे। – sehe

+1

'std :: forward_list' के लिए समान समस्या मौजूद है। Boost.Spirit के संदर्भ में कक्षा के लिए कंटेनर होने के लिए 'push_back' आवश्यक है। – Orient

संबंधित मुद्दे