如果未知数组的大小,如何将函数数组作为参数传递

时间:2013-12-15 14:07:04

标签: c++ argument-passing

这是一个简单的(也是一个愚蠢的,是的)我正在尝试做的例子:

#include <iostream>

void callFunctionsFromAnArray(void *(*)(int), int);
void f1(int);
void f2(int);
void f3(int);

int main()
{
    const int n = 3;
    void (*functions[n]) (int) = { f1, f2, f3 };
    callFunctionsFromAnArray(functions, n);
}

void callFunctionsFromAnArray(void *(*f) (int), int fCount) {
    for (int i = 0; i < fCount; i++)
        f[i](1);
}

void f1(int a)
{
    std::cout << a * 1 << '\n';
}
void f2(int a)
{
    std::cout << a * 2 << '\n';
}
void f3(int a)
{
    std::cout << a * 3 << '\n';
}

这些是我在尝试编译时遇到的错误:

12:9: error: no matching function for call to 'callFunctionsFromAnArray'
        callFunctionsFromAnArray(functions, n);
3:10: note: candidate function not viable: no known conversion from 'void (*[3])(int)' to 'void *(*)(int)' for 1st argument
    void callFunctionsFromAnArray(void *(*)(int), int);
17:13: error: subscript of pointer to function type 'void *(int)'
            f[i](1);
2 errors generated.

但是,如果我将参数更改为void (*f[3]) (int)则可行。但问题是,在运行时之前并不总是能够知道数组的大小(这就是为什么函数毕竟有第二个参数)。有没有解决方案?

2 个答案:

答案 0 :(得分:2)

因为在这种情况下,数组衰减成指针,你不必事先知道它的大小 - 在函数参数声明中,只有那里,指针和数组限定符(*[])是等价的,数组的大小无关紧要。

因此,您可以声明您的函数采用3个(或多个)指针的数组,然后您可以传递一个任何指针的数组:

void callFunctionsFromAnArray(void *(*f[1])(int), int fCount)
{
    for (int i = 0; i < fCount; i++)
        f[i](i);
}

但是,如果你不喜欢这样,你可以让它接受一个指向指针的指针:

void callFunctionsFromAnArray(void *(**f)(int), int fCount); // etc.

但是,如果这真的是C ++,那么最好将const引用传递给std::function s的向量:

void callFunctionsFromAnArray(const std::vector<std::function<void *(int)> > &a)
{
     // call'em
}

答案 1 :(得分:2)

由于您使用的是C ++而不是C,我强烈建议您改用std::vectorstd::function。它们会让你的生活更轻松,特别是在这种特殊情况下:

#include <functional>
#include <vector>

void f1(int);
void f2(int);
void f3(int);

using function_vector = std::vector<std::function<void(int)>>;

void callFunctions(const function_vector& vec) {
    for (const auto& f : vec)
        f(1);
}

int main() {
    function_vector vec = { &f1, &f2, &f3 };
    callFunctions(vec);
}

您可以看到实时示例here