【问题标题】:Store multiple functions into array C++ for looping将多个函数存储到数组 C++ 中以进行循环
【发布时间】:2019-03-14 11:40:54
【问题描述】:

我有两个函数调用

  1. void funcBlock(A a, B b, int C, long& R, long& M, double& D)
  2. void funcNormal(A a, B b, long& R, long& M, double& D)

在 main 方法中,我想通过循环使用这两个函数的值,例如,

主要方法:

combineFunc cfs[] = { funcBlock, funcNormal }
for (int idx = 0; idx < 2; idx++) //Cause it has two functions to loop over
{ 
  combineFunc cf = cfs[idx];

  //Do the rest of the stuffs
}

我遇到错误:

错误:初始化时无法将‘void (*)(A, B, int, long int&, long int&, double&)’转换为‘combineFunc’

我该如何解决这个问题?

【问题讨论】:

  • 什么是combineFunc
  • 它们接受不同的参数类型和不同数量的参数。您如何期望代码知道要传递哪些参数和传递多少参数?
  • 最好告诉我们你想达到什么目标。
  • cfs[] 是一个数组。数组的所有元素都必须属于同一类型。 “函数指针”不是一种类型。每个函数指针必须是同一类型。

标签: c++ arrays function pointers


【解决方案1】:

这是不可能的,因为你的函数有不同的签名(这些是不同的类型)。 C++ 不支持不同类型元素的数组。但是你可以通过添加未使用的参数来匹配签名,它根本不会改变任何东西,但允许你将它们放在一个容器中:

typedef void(*combineFunc)(A, B, int, long int&, long int&, double&);

void funcBlock(A a, B b, int C, long& R, long& M, double& D);
void funcNormal(A a, B b, int unused, long& R, long& M, double& D);

combineFunc cfs[] = { funcBlock, funcNormal };

另一种方法是使用可以存储所有函数的结构数组,就像这样

struct combineFunc
{
   enum TYPE
   {
      NORMAL,
      BLOCK
   } type;

   combineFunc(void(*nf)(A, B, int, long int&, long int&, double&)) :
      type(NORMAL), nf_(nf)
   {
   }

   combineFunc(void(*fb)(A, B, long int&, long int&, double&)) :
      type(BLOCK), fb_(fb)
   {
   }

   union
   {
      void(*nf_)(A, B, int, long int&, long int&, double&);
      void(*fb_)(A, B, long int&, long int&, double&);
   };
};

CombineFunc cfs[] = { funcBlock, funcNormal };

【讨论】:

  • 不,抱歉,我不是这个意思。 unused 这个词本身就很好。如果您愿意,请参阅我的回答。 (但我也喜欢你的回答,+1。​​)
  • 嗨,很遗憾,我无法更改函数参数。所以我猜想把它们存储在一个数组中是不可能的。
  • @user6308605,你使用什么 C++ 标准?
  • c++11 @DmytroDadyka
  • @user6308605,在 C++ 11 中,您可以基于 union 类型创建类似于 std::variant 的容器。查看更新的答案。
【解决方案2】:

你的问题最好用一个问题来回答。

在循环中,当你调用cf(arguments) 时,你会在括号之间写什么参数?参数是否包括C

我认为,如果你回答了这个问题,你就会明白为什么在你的程序重新设计之前你可能无法完成你想要的事情。不过,重新设计可能很简单,就像让 funcNormal() 接受(并忽略)一个虚拟参数来代替 C

如果最后一个建议是你想要的,那么

void funcNormal(A a, B b, int, long& R, long& M, double& D)

请注意,int,因为被忽略,未命名。

【讨论】:

    【解决方案3】:

    C++ 是一种静态类型语言。数组是同构的:数组的所有元素都具有完全相同的类型。

    指向一种类型的函数的指针与指向另一种函数类型的指针是不同的类型。函数的类型由其参数和返回类型决定。因此,不可能将指向不同参数列表的函数的指针存储在同一个数组中。

    然而,有一些“类型擦除”技术,它允许模拟动态类型。 C++ 标准库带有两个异构包装器:std::variantstd::any。变体是标记联合的实现。它可用于存储预定义类型列表中的对象。 anyvoid* 的类型安全包装器。它可以存储任何类型的对象。因此,一组变体或any 可能就是您要查找的内容。

    虽然它们只是低级工具,但对于功能更强大的异构处理,已有 Boost.Hana 等库。

    【讨论】:

      【解决方案4】:

      假设你有一组变量来调用它们,并且它们都有固定的类型,你可以将你的函数包装在 lambdas 中以规范它们的类型:

      using combineFunc = void(*)(A, B, int, long int&, long int&, double&);
      
      combineFunc cfs[] = {
          [](A a, B b, int C, long& R, long& M, double& D){ funcBlock(a, b, C, R, M, D); },
          [](A a, B b, int, long& R, long& M, double& D){ funcNormal(a, b, R, M, D); }
      };
      
      // do whatever
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-24
        • 1970-01-01
        • 2015-03-27
        • 1970-01-01
        • 2021-02-28
        • 1970-01-01
        • 2021-05-24
        • 2019-10-18
        相关资源
        最近更新 更多