使用回调函数

问题描述 投票:0回答:1

我正在学习一个教程系列,其中有一个关于回调函数的课程,其中包含一个简单的计算器。我不擅长编程,但我了解指针和函数。

本教程演示了一个简单的案例,其中有两个接受 (int, int) 的函数和一个接受函数指针作为参数的函数,但我决定对其进行自己的改造,并传递一个 double 数组和两个 size_t 变量(以标记数组的开头和结尾)作为加法和减法函数的参数。

我尝试将三个参数传递给所有函数,并将一个函数指针传递给“操作”函数。 我希望程序根据用户的选择添加或减去数组中的所有数字。

#include <iostream>
#include <cmath>

double add(double[], size_t, size_t);
double subtract(double[], size_t, size_t);

int main()
{
    double numbers[] { 1.3, 2.0, 3.5};
    size_t start = 0;
    size_t end = std::size(numbers);
    double(*operation)(double(*), double numbers[], size_t start, size_t end); // a function pointer
    char choice = '0';  // a char variable for the choice of operation
    double result;  // result of the operation for the output

    std::cin >> choice; // input

    if(choice == '+')
    {
        result = operation(add, numbers, &start, &end); // passing the addition function as an argument to the operation function
    }
    if(choice == '-')
    {
        result = operation(subtract, numbers, &start, &end);
    }
    std::cout << result << std::endl;   // output
}

double add(double numbers[], size_t *start, size_t *end)    // add all numbers in the array
{
    double result = 0;

    for(int i = *start; i < *end; i++)
    {
        result += numbers[i];
    }
    return result;
}

double subtract(double numbers[], size_t start, size_t end) // subtract the following numbers from the first one in the array
{
    double result = 0;

    for(int i = start; i < end; i++)
    {
        result -= numbers[i];
    }
    return result;
}

double operation(double(*op)(double, size_t, size_t), double numbers[], size_t start, size_t end)
{
    return op(numbers, start, end); // the function that accepts two functions as arguments
}

我从编译器得到的错误是:

funcpointerscalc.cpp: In function ‘int main()’:
funcpointerscalc.cpp:20:28: error: cannot convert ‘double (*)(double*, size_t, size_t)’ {aka ‘double (*)(double*, long unsigned int, long unsigned int)’} to ‘double*’ in argument passing
   20 |         result = operation(add, numbers, &start, &end);
      |                            ^~~
      |                            |
      |                            double (*)(double*, size_t, size_t) {aka double (*)(double*, long unsigned int, long unsigned int)}
funcpointerscalc.cpp:24:28: error: cannot convert ‘double (*)(double*, size_t, size_t)’ {aka ‘double (*)(double*, long unsigned int, long unsigned int)’} to ‘double*’ in argument passing
   24 |         result = operation(subtract, numbers, &start, &end);
      |                            ^~~~~~~~
      |                            |
      |                            double (*)(double*, size_t, size_t) {aka double (*)(double*, long unsigned int, long unsigned int)}
funcpointerscalc.cpp: In function ‘double* add(double*, size_t*, size_t*)’:
funcpointerscalc.cpp:37:12: error: invalid type argument of unary ‘*’ (have ‘double’)
   37 |     return *result;
      |            ^~~~~~~
funcpointerscalc.cpp: At global scope:
funcpointerscalc.cpp:40:9: error: ambiguating new declaration of ‘double* subtract(double*, size_t, size_t)’
   40 | double* subtract(double numbers[], size_t start, size_t end)
      |         ^~~~~~~~
funcpointerscalc.cpp:5:8: note: old declaration ‘double subtract(double*, size_t, size_t)’
    5 | double subtract(double[], size_t, size_t);
      |        ^~~~~~~~
funcpointerscalc.cpp: In function ‘double* subtract(double*, size_t, size_t)’:
funcpointerscalc.cpp:48:12: error: invalid type argument of unary ‘*’ (have ‘double’)
   48 |     return *result;
      |            ^~~~~~~
funcpointerscalc.cpp: In function ‘double operation(double (*)(double, size_t, size_t), double*, size_t, size_t)’:
funcpointerscalc.cpp:53:15: error: cannot convert ‘double*’ to ‘double’ in argument passing
   53 |     return op(numbers, start, end);
      |               ^~~~~~~
      |               |
      |               double*

c++ callback
1个回答
0
投票

您的代码中存在一些问题。

这里

double(*operation)(double(*), double numbers[], size_t start, size_t end); // a function pointer

您声明了一个名为

operation
的函数指针。这会影响调用名为
operation
的函数的方式。您现在得到的错误抱怨
add
不是
double*
,因为这就是
operation
的声明方式:第一个参数是
double*
的函数指针。

删除函数指针的声明。现在,您将看到您尝试在声明函数之前调用该函数:https://godbolt.org/z/YsMfqM4ee

像对

add
subtract
那样预先声明函数。您现在将看到错误,因为功能点的签名错误:

double operation(double(*op)(double, size_t, size_t), double numbers[], size_t start, size_t end)

此函数需要一个函数指针作为第一个参数,该函数指针以

double
作为第一个参数。你的
add
和减法得到
double*

接下来,您的一个函数将

start
end
作为另一个按值的指针。那是行不通的。坚持一个。我将按值传递它们,因此:

错误:

result = operation(add, numbers, &start, &end);

正确:

result = operation(add, numbers, start, end);

并相应地调整函数签名。

这就是使您的代码编译的原因:https://godbolt.org/z/3jMPE43Ed。它在语法上是正确的。您现在应该编写测试来查看它是否执行了预期的操作。对于测试不要依赖

std::cin
。对于频繁的测试并且您想要可重复的运行来说太不方便了。在代码中编写示例,您可以直接比较预期结果和实际结果。

© www.soinside.com 2019 - 2024. All rights reserved.