我有两个叫做
的函数void funcBlock(A a, B b, int C, long& R, long& M, double& D)
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”
我该如何解决?
答案 0 :(得分:4)
最好用一个问题回答您的问题。
在循环中,当您调用cf(arguments)
时,您将在括号之间写入哪些参数?参数是否包含C
?
我认为,如果您回答了这个问题,您将看到为什么要重新设计程序之前可能无法完成所需的操作。不过,重新设计可能很简单,就像让funcNormal()
代替C
接受(并忽略)虚拟参数一样。
如果最后一个建议是您想要的,那么
void funcNormal(A a, B b, int, long& R, long& M, double& D)
请注意,int
由于被忽略而未命名。
答案 1 :(得分:3)
这是不可能的,因为您的函数具有不同的签名(这些是不同的类型)。 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 };
答案 2 :(得分:3)
C ++是一种静态类型的语言。数组是同质的:数组的所有元素都具有完全相同的类型。
指向一种类型的函数的指针与指向另一种函数类型的指针是不同的类型。函数的类型由其参数和返回类型确定。因此,不可能在同一数组中存储指向不同参数列表的函数的指针。
但是,有一些用于“类型擦除”的技术,该技术可以模拟动态类型。 C ++标准库带有两个异构包装器:std::variant
和std::any
。 Variant是带标签的联合的实现。它可用于存储预定义类型列表中的对象。 any
是void*
的类型安全包装器。它可以存储任何类型的对象。因此,您可能正在寻找变量或any
的数组。
尽管它们只是底层工具,而且对于更具特色的异构处理,还有现有的库,例如Boost.Hana。
答案 3 :(得分:1)
假设您有一组变量可以调用它们,并且它们都有固定的类型,则可以将函数包装在lambda中以标准化它们的类型:
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