I would like to reuse code by writing a proto transform which is templated by a function pointer:
template <typename Ret, typename A0, typename A1, Ret func(A0,A1)>
struct apply_func : proto::callable
{
// Do something with func
};
However, the function itself is polymorphic so I do not want to specify its exact signature.
A simplified version of what I would like my code to look like follows (I am using external transforms for a technical reason that I think is unrelated to my current question - I could not get the recursion working without them):
template<typename R, typename A0, typename A1>
R plus_func(A0 lhs, A1 rhs) { return lhs+rhs; }
template<typename R, typename A0, typename A1>
R minus_func(A0 lhs, A1 rhs) { return lhs-rhs; }
struct my_grammar;
struct plus_rule : proto::plus<my_grammar, my_grammar> {};
struct minus_rule : proto::minus<my_grammar, my_grammar> {};
struct my_grammar
: proto::or_<
proto::when<proto::terminal<proto::_>, proto::_value>
, proto::when<plus_rule, proto::external_transform >
, proto::when<minus_rule, proto::external_transform >
>
{};
struct my_external_transforms
: proto::external_transforms<
proto::when<plus_rule, apply_func<plus_func>(my_grammar(proto::_left),my_grammar(proto::_right), proto::_state)>
, proto::when<minus_rule, apply_func<minus_func>(my_grammar(proto::_left),my_grammar(proto::_right), proto::_state)>
>
{};
That does not compile because there are missing arguments to the appy_func template. Is there a solution?
Function templates are similar to class templates but define a family of functions. With function templates, you can specify a set of functions that are based on the same code but act on different types or classes.
A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. template <typename T> T functionName(T parameter1, T parameter2, ...) { // code }
Template Method in C++ Template Method is a behavioral design pattern that allows you to defines a skeleton of an algorithm in a base class and let subclasses override the steps without changing the overall algorithm's structure.
You have multiple problem in your code:
Perusing your pseudo code, I'll go for something like :
struct plus_func
{
template<class Sig> struct result;
template<class This,class A, class B>
struct result<This(A,B)>
{
typedef /*whatever*/ type;
};
template<class A, class B>
typename result<plus_func(A const&,B const&)>::type
plus_func(A const& lhs, B const& rhs)
{
return lhs+rhs;
}
};
struct minus_func
{
template<class Sig> struct result;
template<class This,class A, class B>
struct result<This(A,B)>
{
typedef /*whatever*/ type;
};
template<class A, class B>
typename result<minus_func(A const&,B const&)>::type
plus_func(A const& lhs, B const& rhs)
{
return lhs-rhs;
}
};
struct my_grammar;
struct plus_rule : proto::plus<my_grammar, my_grammar> {};
struct minus_rule : proto::minus<my_grammar, my_grammar> {};
struct my_grammar
: proto::or_<
proto::when<proto::terminal<proto::_>, proto::_value>
, proto::when<plus_rule, proto::external_transform >
, proto::when<minus_rule, proto::external_transform >
>
{};
struct my_external_transforms
: proto::external_transforms<
proto::when<plus_rule, apply_func<plus_func>(my_grammar(proto::_left),my_grammar(proto::_right), proto::_state)>
, proto::when<minus_rule, apply_func<minus_func>(my_grammar(proto::_left),my_grammar(proto::_right), proto::_state)>
>
{};
Type returned by each PFO has to be computed or specified. Beware that A,B can be const/ref qualified and may need stripping before doing type computation.
Sidenote : external_transform are not required at all for recursive rules. I guess point 4 (template callable) was what made it not work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With