Static polymorphism

O

Olaf

Hello,

for my data parser I want to use different generic checking policies
using static polymorphism. But the way I've used won't compile (concrete
the grammar class). The check policy passes the data the parse actions
which fills (and knows about) the data container.

What is the correct syntax for this? Note, that boost::spirit::grammar
self uses static polymorphism.

Thanks,
Olaf

---8<---
struct parse_actions { ... };

struct parse_error_handler { ... };

template<typename DerivedT, typename ActionsT>
struct check_policy
{
explicit check_policy( const ActionsT& actions )
...
};

template <typename ActionsT = parse_actions,
typename CheckPolicyT = check_policy,
typename ErrorHandlerT = parse_error_handler>
struct grammar :
CheckPolicyT< grammar<CheckPolicyT, ActionsT, ErrorHandlerT> >,
boost::spirit::grammar<
grammar said:
{
explicit grammar(const ActionsT& actions = ActionsT(),
const ErrorHandlerT& handler = ErrorHandlerT())
: CheckPolicyT( actions ),
actions(actions),
error_handler(handler)
{ }

--->8---
 
A

acehreli

You need to read about "template template parameters". Notice
'template' before CheckPolicyT below:

template <typename ActionsT = parse_actions,
template <typename, typename> class CheckPolicyT =
check_policy,
typename ErrorHandlerT = parse_error_handler>
struct grammar :
/* ... */

A compilable sample is below...

Hello,

for my data parser I want to use different generic checking policies
using static polymorphism. But the way I've used won't compile (concrete
the grammar class). The check policy passes the data the parse actions
which fills (and knows about) the data container.

What is the correct syntax for this? Note, that boost::spirit::grammar
self uses static polymorphism.

Thanks,
Olaf

---8<---
struct parse_actions { ... };

struct parse_error_handler { ... };

template<typename DerivedT, typename ActionsT>
struct check_policy
{
explicit check_policy( const ActionsT& actions )
...

};

template <typename ActionsT = parse_actions,
typename CheckPolicyT = check_policy,
typename ErrorHandlerT = parse_error_handler>
struct grammar :
CheckPolicyT< grammar<CheckPolicyT, ActionsT, ErrorHandlerT> >,
boost::spirit::grammar<

{
explicit grammar(const ActionsT& actions = ActionsT(),
const ErrorHandlerT& handler = ErrorHandlerT())
: CheckPolicyT( actions ),
actions(actions),
error_handler(handler)
{ }

--->8---

struct parse_actions { };

struct parse_error_handler { };

template<typename DerivedT, typename ActionsT>
struct check_policy
{
explicit check_policy( const ActionsT& actions )
{}
};

template <typename ActionsT = parse_actions,
template <typename, typename> class CheckPolicyT =
check_policy,
typename ErrorHandlerT = parse_error_handler>
struct grammar :
CheckPolicyT< grammar<parse_actions, CheckPolicyT, ErrorHandlerT>,
ActionsT >,
boost::spirit::grammar<
grammar said:
{
explicit grammar(const ActionsT& actions = ActionsT(),
const ErrorHandlerT& handler = ErrorHandlerT())
: CheckPolicyT<grammar<ActionsT, CheckPolicyT, ErrorHandlerT>,
ActionsT>( actions )
{ }
};

Ali
 
O

Olaf

Thanks a lot, Ali.

After thinking more about which/what has to derive I wrote this (the
problem/principle is the same):

---8<---
template<typename DerivedT, typename ActionsT>
struct check_policy
{
explicit check_policy( const ActionsT& actions )
: on_data_ver( actions ),
...
{ }

struct on_data_ver_action
{
explicit on_data_ver_action( const ActionsT& actions )
: action( actions )
{ }

void operator()(const data_ver& version) const {
action.set_data_ver( version );
}

const ActionsT& action;
};
const on_data_ver_action on_data_ver;
...
};

template <typename ActionsT = parse_actions,
template <typename, typename>
class CheckPolicyT = check_policy,
typename ErrorHandlerT = parse_error_handler>
struct grammar :
sp::grammar<
grammar said:
{
explicit grammar(const ActionsT& actions = ActionsT(),
const ErrorHandlerT& handler = ErrorHandlerT())
: actions(actions),
error_handler(handler)
{ }

template <typename ScannerT>
struct definition
: CheckPolicyT< definition<ScannerT>, ActionsT >
{
...

explicit definition( const grammar& self )
: CheckPolicyT< definition<ScannerT>, ActionsT >(
self.actions )
{
using namespace ::boost::spirit;
using namespace ::phoenix;

const ErrorHandlerT& error_handler = self.error_handler;

guard<parse_error> g;

document
= g(
expect_data_ver(
data_ver_p[on_data_ver]
)
...
--->8---

ext_parser.cpp: In constructor 'grammar<ActionsT, CheckPolicyT,
ErrorHandlerT>::definition<ScannerT>::definition(const grammar<ActionsT,
CheckPolicyT, ErrorHandlerT>&)':
ext_parser.cpp:564: error: 'on_data_ver' was not declared in this scope

It seems, that the member function on_data_ver is not visible in the
derived (sub class definition) scope.

Did I something wrong?

Thanks,
Olaf
 
A

acehreli

template<typename DerivedT, typename ActionsT>
struct check_policy
{ [...]
struct on_data_ver_action
{ [...]
};
const on_data_ver_action on_data_ver;
...

};

template <typename ActionsT = parse_actions,
template <typename, typename>
class CheckPolicyT = check_policy,
typename ErrorHandlerT = parse_error_handler>
struct grammar :
sp::grammar<
grammar said:
[...]

template <typename ScannerT>
struct definition
: CheckPolicyT< definition<ScannerT>, ActionsT >
{
...

explicit definition( const grammar& self )
: CheckPolicyT< definition<ScannerT>, ActionsT >(
self.actions )
{ [...]
document
= g(
expect_data_ver(
data_ver_p[on_data_ver]
error: 'on_data_ver' was not declared in this scope

This is already beyond my template knowledge :) Here is my guess:
on_data_ver is not known when the template is compiled. It is just an
unknown name at that time. It may be known when the template is
instantiated.

This solved the problem for g++:

typedef CheckPolicyT< definition<ScannerT>, ActionsT > Parent;

/* ... */ data_ver_p[Parent::eek:n_data_ver]

I guess that way, the name becomes dependent on one of the template
parameters and the compiler delays the resolution to instantiation
time. (This sounds technical, but I wouldn't rely on it! :) )

Ali
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top