6

我想通过编写一个由函数指针模板化的原型转换来重用代码:

template <typename Ret, typename A0, typename A1, Ret func(A0,A1)>
struct apply_func : proto::callable
{
  // Do something with func
};

但是,函数本身是多态的,所以我不想指定它的确切签名。

我希望我的代码如下所示的简化版本(出于技术原因,我使用外部转换,我认为这与我当前的问题无关 - 没有它们我无法使递归工作):

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)>
    >
{};

这不会编译,因为 appy_func 模板缺少参数。有解决办法吗?

4

1 回答 1

3

您的代码中有多个问题:

  • 您不能在不指定模板参数的情况下获取模板函数指针,因为在函数实例化之前模板将不存在。
  • 第二点, Ret(A,B) 是函数类型而不是函数指针类型。
  • 随着抽象的发展,函数指针有点原始,同样可以通过仿函数来实现,它也可以解决您的问题,因为多态函数对象是单一的非模板类型。
  • 最后的技术点,模板转换不能使用 proto::callable,你必须明确地专门化 boost::proto::is_callable。这是由于对如何检测继承的语言限制。

仔细阅读您的伪代码,我将使用以下内容:

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)>
    >
{};

必须计算或指定每个 PFO 返回的类型。请注意 A,B 可以是 const/ref 限定的,并且在进行类型计算之前可能需要剥离。

旁注:递归规则根本不需要 external_transform。我猜第 4 点(模板可调用)是它不起作用的原因。

于 2012-03-09T15:49:31.377 回答