Доброго всем времени суток. Случилась такая проблема: при попытке завернуть std::get в функциональный объект boost::spirit::phoenix вываливается здоровенный листинг ошибок на предмет того (как я смог понять), что такую сигнатуру использовать не получится. Как можно заставить собираться нижеприведённый код, и можно ли это сделать вообще?
#include <tuple>
#include <vector>
#include <string>
#include <iostream>
//--------------------------------------------------------------------------
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
//--------------------------------------------------------------------------
/*
g++ -Wall -std=gnu++0x -o ./main ./main.cpp
*/
//--------------------------------------------------------------------------
namespace qi = boost::spirit::qi;
namespace ph = boost::phoenix;
//--------------------------------------------------------------------------
typedef std::tuple<int,int,float> TpPointsTuple;
typedef std::vector<TpPointsTuple> TpPointsTempStorage;
//--------------------------------------------------------------------------
struct phoenix_get_impl
{
template <std::size_t I,typename... Args>
struct result
{
typedef typename std::tuple_element<I,std::tuple<Args...>>::type type;
};
template <std::size_t I,typename... Args>
typename result<I,Args...>::type& operator () (std::tuple<Args...>& t)
{
return std::get<I> (t);
}
};
ph::function<phoenix_get_impl> const phoenix_get = phoenix_get_impl();
//--------------------------------------------------------------------------
struct phoenix_make_tuple_impl
{
template <typename... Args>
struct result
{
typedef std::tuple<Args...> type;
};
template <typename... Args>
typename result<Args...>::type operator () (Args... args) const
{
return std::make_tuple(args...);
}
};
ph::function<phoenix_make_tuple_impl> const phoenix_make_tuple = phoenix_make_tuple_impl();
//--------------------------------------------------------------------------
template <typename Iterator> \
struct TpPointsParser : qi::grammar \
<Iterator,TpPointsTempStorage(),qi::space_type> \
{
TpPointsParser(void) : TpPointsParser::base_type(start)
{
int_strong %= qi::int_ >> !(qi::punct >> *qi::digit);
sectionName = qi::alpha >> *qi::alnum >> qi::lit('=');
requiredData = (int_strong >> int_strong >> -qi::float_) \
[phoenix_make_tuple(qi::_1,qi::_2,qi::_3)];
start = sectionName >> requiredData \
//[ph::push_back(qi::_val,qi::_1)];
[std::cerr << phoenix_get.operator () <0> (qi::_1)];
return;
}
qi::rule<Iterator,int()> int_strong;
qi::rule<Iterator,void(),qi::space_type> sectionName;
qi::rule<Iterator,TpPointsTuple(),qi::space_type> requiredData;
qi::rule<Iterator,TpPointsTempStorage(),qi::space_type> start;
};
//--------------------------------------------------------------------------
int main(int argc,char** argv)
{
//#define USE_IT
#ifdef USE_IT
std::tuple<int,int> t(100500,9000);
phoenix_get_impl pgi;
std::cerr << pgi.operator () <0> (t) << std::endl;
#else
std::string data("point0 = 9000 100500\n");
std::string::const_iterator walker = data.begin();
std::string::const_iterator end = data.end();
bool result = true;
TpPointsTempStorage tpPointsTempStorage;
TpPointsParser<std::string::const_iterator> tpPointsParser;
while((walker != end) && (result == true))
{
result = qi::phrase_parse(walker,end,tpPointsParser,qi::space,tpPointsTempStorage);
std::cerr << std::endl;
}
std::cerr << "tpPointsTempStorage.size() = " \
<< tpPointsTempStorage.size() \
<< std::endl;
#endif//USE_IT
return 0;
}