2013-03-16 49 views
2

我試圖訪問我的業力語法中的指針向量,但很少成功。指針類型是不可複製,因此規則使用它必須採取的引用:精神業力:訪問不可複製的指針

#include <boost/spirit/include/karma.hpp> 
#include <boost/fusion/adapted/struct/adapt_struct.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 

namespace karma = boost::spirit::karma; 
namespace fusion = boost::fusion; 
namespace phx = boost::phoenix; 

struct test1 : boost::noncopyable { 
    test1(int i = 0) : value(i) {} 
    int value; 
}; 

struct test2 : boost::noncopyable { 
    int value; 
    std::vector<test1*> vector; 
}; 

BOOST_FUSION_ADAPT_STRUCT(test1, (int, value)); 
BOOST_FUSION_ADAPT_STRUCT(test2, (int, value) (std::vector<test1*>, vector)); 

typedef std::ostream_iterator<char> Iterator; 

int main() { 

    karma::rule<Iterator, test1*()> t1r; 
    karma::rule<Iterator, test2&()> t2r; 

    t2r %= "test 2 rule:" << karma::int_ << karma::eol << (t1r % karma::eol); 
    t1r %= "test 1 rule: " << karma::int_; 

    std::stringstream stream; 
    std::ostream_iterator<char> out(stream); 

    test2 t; 
    t.vector.push_back(new test1(2)); 
    t.vector.push_back(new test1(3)); 
    t.vector.push_back(new test1(4)); 
    t.vector.push_back(new test1(5)); 
    t.value = 1; 

    karma::generate(out, t2r, t);  
    std::cout<<stream.str()<<std::endl; 
} 

此編譯,但返回:試驗2規則:1,試驗1規則:25104656,試驗1個規則:25104720等上。我知道,在這個簡單的情況下,我可以做

t1r = "test 1 rule: " << karma::int_[karma::_1 = phx::bind(&test1::value, *karma::_val)]; 

解決這個問題,但在現實中是另一個不可複製類型的前人的精力被傳遞到語法,因此我需要使用結構適應在做這個例子。

我也意識到如前所述的here提到的關鍵點deref_iterator,但是,我在模板庫上工作,並且認爲可以使用模板相關類型來專門化deref_iterator。

關於如何使示例工作的任何想法?

+2

我不知道這是否是做到這一點的最好辦法,但[這](http://liveworkspace.org/code/3boUSk $ 0)似乎工作。與deref_iterator不同的是,部分專門化它非常簡單,就像[this](http://liveworkspace.org/code/3boUSk$1)(注意,雖然它顯然不可能適應具有非類型模板參數的模板化結構使用BOOST_FUSION_ADAPT_TPL_STRUCT) – 2013-03-16 17:34:02

+0

@llonesmiz你會使這個習慣嗎?我的意思是,您可以將整個評論提交給一個答案,我很樂意在找到答案時對其進行擴展。如果我認爲我真的會添加不同的東西,我只會添加我自己的答案 – sehe 2013-03-17 03:01:13

+0

非常感謝IIonesmiz,這似乎工作。現在將它移植到我的代碼中!我怎樣才能接受你的評論作爲答案?或者我應該自己發佈解決方案作爲答案? – ickby 2013-03-17 17:08:26

回答

1

llonesmiz在評論中回答了我的問題,所以我發佈了他的內部以備將來參考。使用定製點變換屬性這個問題是可以解決這樣的:

#include <boost/spirit/include/karma.hpp> 
#include <boost/fusion/adapted/struct/adapt_struct.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 

namespace karma = boost::spirit::karma; 
namespace fusion = boost::fusion; 
namespace phx = boost::phoenix; 

template <typename Value1, typename Value2> 
struct test1 : boost::noncopyable { 
    test1(Value1 i = Value1(), Value2 j = Value2()): value1(i),value2(j) {} 
    Value1 value1; 
    Value2 value2; 
}; 

struct test2 : boost::noncopyable { 
    int value; 
    std::vector<test1<int,double>*> vector; 
}; 

BOOST_FUSION_ADAPT_TPL_STRUCT(
(Value1)(Value2), 
(test1) (Value1)(Value2), 
(Value1, value1) 
(Value2, value2)) 

typedef std::vector<test1<int,double>*> test1_vector; 

BOOST_FUSION_ADAPT_STRUCT(test2, (int, value) (test1_vector, vector)) 

typedef std::ostream_iterator<char> Iterator; 

namespace boost { namespace spirit { namespace traits 
{ 
template <typename Value1, typename Value2> 
struct transform_attribute<test1<Value1,Value2>* const, test1<Value1,Value2>&, karma::domain> 
{ 
    typedef test1<Value1,Value2>& type; 
    static type pre(test1<Value1,Value2>* const& val) 
    { 
     return *val; 
    } 
}; 
}}} 

int main() { 

    karma::rule<Iterator, test1<int,double>*()> t1r; 
    karma::rule<Iterator, test2&()> t2r; 

    t2r %= "test 2 rule:" << karma::int_ << karma::eol << (t1r % karma::eol); 
    t1r %= "test 1 rule: " << karma::attr_cast<test1<int,double>*,test1<int,double>&>(karma::delimit(karma::space)[karma::int_<< karma::double_]); 

    std::stringstream stream; 
    std::ostream_iterator<char> out(stream); 

    test2 t; 
    t.vector.push_back(new test1<int,double>(2)); 
    t.vector.push_back(new test1<int,double>(3)); 
    t.vector.push_back(new test1<int,double>(4)); 
    t.vector.push_back(new test1<int,double>(5)); 
    t.value = 1; 

    karma::generate(out, t2r, t);  
    std::cout<<stream.str()<<std::endl; 
} 
+0

[另一種選擇](http://liveworkspace.org/code/24BvYL$0)使用'deref_iterator'。我希望這會是一個更好的解決方案,但正如你所看到的......事實並非如此。 – 2013-03-20 10:51:01