【问题标题】:How do I pass an array of functions as argument if size of array isn't known如果数组的大小未知,如何将函数数组作为参数传递
【发布时间】:2013-12-15 14:07:04
【问题描述】:

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

#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) 它可以工作。但问题是,在运行时之前并不总是可以知道数组的大小(这就是为什么函数毕竟有第二个参数)。有什么解决办法吗?

【问题讨论】:

  • 对函数类型使用typedef 通常是个好主意,以帮助避免这个问题。
  • std::vectorstd::function 怎么样?

标签: c++ argument-passing


【解决方案1】:

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

因此,您可以声明您的函数接受一个包含 3 个(或多个)指针的数组,然后您可以将一个 any 指针数组传递给它:

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::functions 的向量:

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

【讨论】:

  • +1,虽然我认为可能需要 void (**f) (int),但基于被调用的函数(我认为 OP 基本上只是放错了 *)。
  • @OliCharlesworth 听起来很合理。让我们看看 OP 的真正含义。与此同时,我还添加了一个更 C++ 风格的解决方案。
  • 不正确:“数组总是,在传递给函数时无条件地衰减为指针”
  • @Cheersandhth.-Alf 谢谢!有什么例外?
  • 主要是当形式参数是引用时。哦,好吧,想想这是唯一的例外。
【解决方案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

【讨论】:

  • 请加const几个地方,以免教坏编程习惯(TM)。
  • @Cheersandhth.-Alf,听起来不错。由于某些原因,我认为std::function 中的operator() 没有声明为const
猜你喜欢
  • 2015-03-18
  • 2011-08-20
  • 1970-01-01
  • 2012-04-27
  • 2018-01-13
  • 2021-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多