Ошибка компиляции Spirit X3 «объявление шаблона не может отображаться в области видимости блока»

я пытаюсь небольшой пример, чтобы начать с Spirit X3.

template <typename Iterator>
bool parser(Iterator& first, Iterator const& last)
{
using namespace x3;

x3::rule<class quote,std::string> const quote = "quote";
auto quote_def = '"' >> *(char_-'"') >> '"';

//   x3::rule<class header,std::vector<std::string>> const header = "header";
//  auto header_def = quote % ',';

BOOST_SPIRIT_DEFINE(quote);

return true;
}

int main(int argc, char** argv)
{
std::string test = "\"abc\",\"def\"";

auto it=std::begin(test);
parser( it, std::end(test));

return 0;
}

И я получаю следующую ошибку компилятора:

In file included from /home/robstr/Downloads/boost_1_60_0/boost/spirit/home/x3/nonterminal.hpp:10:0,
from /home/robstr/Downloads/boost_1_60_0/boost/spirit/home/x3.hpp:17,
from tmp.cc:5:
tmp.cc: In function ‘bool parser(Iterator&, const Iterator&)’:
/home/robstr/Downloads/boost_1_60_0/boost/spirit/home/x3/nonterminal/rule.hpp:157:5: error: a template declaration cannot appear at block scope
template <typename Iterator, typename Context, typename Attribute>          \
^
/home/robstr/Downloads/boost_1_60_0/boost/preprocessor/seq/for_each.hpp:83:61: note: in expansion of macro ‘BOOST_SPIRIT_DEFINE_’
# define BOOST_PP_SEQ_FOR_EACH_M_I(r, macro, data, seq, sz) macro(r, data, BOOST_PP_SEQ_HEAD(seq))
^
/home/robstr/Downloads/boost_1_60_0/boost/preprocessor/seq/for_each.hpp:78:47: note: in expansion of macro ‘BOOST_PP_SEQ_FOR_EACH_M_I’
#    define BOOST_PP_SEQ_FOR_EACH_M_IM(r, im) BOOST_PP_SEQ_FOR_EACH_M_I(r, im)
^
/home/robstr/Downloads/boost_1_60_0/boost/preprocessor/seq/for_each.hpp:77:43: note: in expansion of macro ‘BOOST_PP_SEQ_FOR_EACH_M_IM’
#    define BOOST_PP_SEQ_FOR_EACH_M(r, x) BOOST_PP_SEQ_FOR_EACH_M_IM(r, BOOST_PP_TUPLE_REM_4 x)
^
/home/robstr/Downloads/boost_1_60_0/boost/preprocessor/seq/for_each.hpp:77:73: note: in expansion of macro ‘BOOST_PP_TUPLE_REM_4’
#    define BOOST_PP_SEQ_FOR_EACH_M(r, x) BOOST_PP_SEQ_FOR_EACH_M_IM(r, BOOST_PP_TUPLE_REM_4 x)
^
/home/robstr/Downloads/boost_1_60_0/boost/preprocessor/control/iif.hpp:32:31: note: in expansion of macro ‘BOOST_PP_SEQ_FOR_EACH_M’
# define BOOST_PP_IIF_1(t, f) t
^
/home/robstr/Downloads/boost_1_60_0/boost/preprocessor/repetition/detail/for.hpp:22:37: note: in expansion of macro ‘BOOST_PP_FOR_1_C’
# define BOOST_PP_FOR_1(s, p, o, m) BOOST_PP_FOR_1_C(BOOST_PP_BOOL(p(2, s)), s, p, o, m)
^
/home/robstr/Downloads/boost_1_60_0/boost/preprocessor/cat.hpp:29:34: note: in expansion of macro ‘BOOST_PP_FOR_1’
#    define BOOST_PP_CAT_I(a, b) a ## b
^
/home/robstr/Downloads/boost_1_60_0/boost/preprocessor/control/iif.hpp:32:31: note: in expansion of macro ‘BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK_EXEC’
# define BOOST_PP_IIF_1(t, f) t
^
/home/robstr/Downloads/boost_1_60_0/boost/preprocessor/seq/for_each.hpp:29:53: note: in expansion of macro ‘BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK’
#    define BOOST_PP_SEQ_FOR_EACH(macro, data, seq) BOOST_PP_SEQ_FOR_EACH_DETAIL_CHECK(macro, data, seq)
^
/home/robstr/Downloads/boost_1_60_0/boost/spirit/home/x3/nonterminal/rule.hpp:169:34: note: in expansion of macro ‘BOOST_PP_SEQ_FOR_EACH’
#define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH(                         \
^
src/dico.cc:21:1: note: in expansion of macro ‘BOOST_SPIRIT_DEFINE’
BOOST_SPIRIT_DEFINE(quote);
^

Проблема в том, я думаю BOOST_SPIRIT_DEFINE но я понятия не имею, как это исправить.

1

Решение

После игры arround я нашел решение:

Вам нужно заключить правило в собственное пространство имен:

namespace grammer
{
using namespace x3;

x3::rule<class quote,std::string> const quote = "quote";
auto quote_def = '"' >> *(char_-'"') >> '"';

x3::rule<class header,std::vector<std::string>> const header = "header";
auto header_def = quote % ',';BOOST_SPIRIT_DEFINE(quote, header);
}template <typename Iterator>
bool parser(Iterator& first, Iterator const& last)
{
using namespace x3;
std::vector<std::string> headerVec;

auto ret = x3::parse( first, last, grammer::header , headerVec);
if(ret)
std::cout << "all done " << headerVec.size() <<"\n";
else
{
std::cout << "not : " << headerVec.size() <<"\n";
}
return true;
}

Но я не могу объяснить, почему это решает ошибку компилятора.

0

Другие решения

Других решений пока нет …