【问题标题】:How to properly create an array of member template function pointers via meta programming如何通过元编程正确创建成员模板函数指针数组
【发布时间】:2015-10-27 22:39:37
【问题描述】:

我想预先创建一个模板成员函数指针数组,它将使用另一个类在运行时确定的变量进行索引。然后可以专门化模板函数。

这适用于non-template class,但是我在模板类中遇到了问题。应用程序有多个 main,它们为 MatchT 定义了不同的模板参数,希望这在代码示例中具有代表性:

#include Data.H  // POD object.
template<typename MatchT>
class Manager
{ 
    public:

    template <int P>
    bool do(Data& d_);

     template<int P, int ...Ps>
     struct table : table<P-1, P-1, Ps... >{};

     template<int... Ps>
     struct table <0, Ps...>
     {
          static constexpr bool(*fns[])(Data&)={do<Ps>...};
     };
  };

   template <typename MatchT>
   template<int... Ps>
   constexpr bool(*Manager<MatchT>::table<0,Ps...>::fns[sizeof...(Ps)])();


//process.h

 #include "Manager.H"

template<typename MatchT>
class Process
{
   public:

   void send(Manager<MatchT>& mgr  );

   private:

    typename Manager<MatchT>::template table<4> _processtable;
};

 //process.c

 template<typename MatchT>
 void Process<MatchT>::send(Manager<MatchT>& mgr)
 {
     ERROR here:
     mgr.*_processtable::fns[1]();
 }

ERROR:
In instantiation of "constexpr bool (* const Manager<MyManager<MyConfig>   >::table<0,0,1,2,3>::fns[4](Data&) 

required from "process.C"...
required from "manager.H" error no  matches converting function 'do' to     type 'bool (* const)(struct Data&)'
   static constexpr bool(*fns[])(Data&) = {do<Ps>...};
note:candidate  is: template<int P> bool Manager<MatchT>::do(Data&) [with int P = P; MatchT = DummyMatch]

  required from "process.C"...
required from "manager.H" error no  matches converting function 'do' to     type 'bool (* const)(struct Data&)'
   static constexpr bool(*fns[])(Data&) = {do<Ps>...};
note:candidate  is: template<int P> bool Manager<MatchT>::do(Data&) [with int P = P; MatchT = MyMatch<MyConfig> >]

我想知道模板类中的静态static constexpr bool(*fns[])(Data&amp;)={do&lt;Ps&gt;...}; 是否会导致问题。是否无法将每个 Manager&lt;MatchT&gt; 类型的函数定义为静态函数?我错过了什么?

【问题讨论】:

  • 你的意思是dostatic 吗?非静态成员函数不能转换为函数指针。
  • 啊没听懂。我不能做静态,因为函数中的代码引用了我也不能静态的其他成员。如果我从 fns 的声明中删除 static,我该如何定义它?
  • 啊,所以你的意思是fns 是指向成员函数的指针数组,而不是函数指针。
  • 是的,如果不清楚,对不起。另外,如果我将 do 设为静态,我不确定如何在 do 中引用实例成员。它只是 Manager ::实例成员?这对每个 MatchT 是否正确?
  • 实际上我有一个在非模板类上工作的简化示例,其中 processTable 在 main 中声明。指向的函数在该类中不是静态的..

标签: c++ template-specialization template-meta-programming


【解决方案1】:

您将fns 声明并定义为指向函数的指针数组,而实际上它需要是指向成员函数的指针数组。试试:

template<typename MatchT>
class Manager
{ 
    public:

    template <int P>
    bool do(Data& d_);

     template<int P, int ...Ps>
     struct table : table<P-1, P-1, Ps... >{};

     template<int... Ps>
     struct table <0, Ps...>
     {
          static constexpr bool(Manager::*fns[])(Data&)={&Manager::do<Ps>...};
     };
};

template <typename MatchT>
template<int... Ps>
constexpr bool(Manager<MatchT>::*Manager<MatchT>::table<0,Ps...>::fns[sizeof...(Ps)])(Data&);

【讨论】:

  • 实际上很抱歉它确实有效,但是我在“mgr.*_processtable::fns[1]();”这一行收到了一个奇怪的错误。它的意思是“错误:必须使用 '.*' 或 '->*' 来调用 'Manager >::table:: 中的指向成员函数的指针fns[1] (...)',例如 '(... ->* Manager >::table::fns[1]) (. ..)'
  • @ggs .* 绑定不如函数调用紧密,因此需要括号。
  • 啊,你是对的!我只是在 aschepler 的例子中注意到了这一点。非常感谢你..我正在努力解决这个问题。
  • 对此的最后一个问题.. 如果我想对“P”和“Ps”使用枚举而不是 int,这样当我专门化函数时,我可以使用枚举类型,是可能的?我尝试过,但收到错误“从 'int' 到 'p_type' 行的无效转换“结构表:表{};”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-07
  • 2017-03-30
  • 2021-11-18
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
相关资源
最近更新 更多