简体   繁体   English

将函数作为参数CPP传递

[英]Passing a function as a parameter CPP

I am attempting to call a class function in my main program that takes a function as its parameter, and applies the function to a private list. 我试图在我的主程序中调用一个以函数作为参数的类函数,并将该函数应用于私有列表。 I am getting the error invalid conversion from char to char (*f)(char) . 我收到错误invalid conversion from char to char (*f)(char) Hopefully I just don't understand how to pass functions as paremeters. 希望我只是不明白如何将函数作为参数传递。 The following are functions in my main cpp file 以下是我的主cpp文件中的函数

char ToUpper(char c)
{
char b='A';
for(char a='a';a<='z';a++)
{
   if(a==c)
  {
     c=b;
     break;
  }
  ++b;
}
return c;
}

void upperList(LineEditor line)
{
char c;
for(int i=0;i<100;i++)   //ensure iterator is at beginning of line
  line.left();           

for(int i=0;i<100;i++)
{
  c=line.at();               //assign character current element pointed to by iterator
  line.apply(ToUpper(c));    //problem: trying to apply ToUpper function to char c
  line.right();              //apply function and increment iterator
}
}

And this is the apply member function 这是apply成员函数

void LineEditor::apply(char (*f)(char c))
{
*it=f(c);
}

Also, in case it wasn't obvious, I tried using the cctypes toupper and tolower but they take and return integers. 此外,如果它不明显,我尝试使用cctypes toupper和tolower但他们采取并返回整数。

When you call ToUpper , it doesn't return the function, it returns the (supposed) character in its uppercase form. 当您调用ToUpper ,它不返回该函数,它以大写形式返回(假定的)字符。

Another reason this doesn't work is because you cannot create arguments inside the signature of a function pointer. 这不起作用的另一个原因是因为您无法在函数指针的签名内创建参数。 The area for the parameter only designates the type that the function takes. 参数的区域仅指定函数所采用的类型。 This... 这个...

char (*f)(char c);
//        ^^^^^^

is therefore wrong. 因此是错误的。

Solution: 解:

Use a std::function and std::bind it to an argument: 使用std::functionstd::bindstd::bind到一个参数:

#include <functional>

line.apply(std::bind(ToUpper, c));

It requires the signature of apply to be changed to: 它要求将apply的签名更改为:

void LineEditor::apply(std::function<char (char)> f);

If you can't do this, you can simply let apply take a second parameter as the argument: 如果你不能这样做,你可以简单地让apply取第二个参数作为参数:

void LineEditor::apply(char (*f)(char), char c);

and call it as apply(ToUpper, c) . 并将其称为apply(ToUpper, c)

表达式ToUpper(c)调用该函数,但是当调用apply你不想立即调用该函数,所以你需要说apply(ToUpper) ,因为ToUpper是访问函数本身的方法。

the type of expression ToUpper(c) is char. 表达式ToUpper(c)的类型是char。 So call 所以打电话

line.apply(ToUpper(c));

means to call function apply with argument of type char. 表示使用char类型的参数调用函数apply。

You should define the function as 您应该将函数定义为

void LineEditor::apply( char c, char f(char) )
{
*it=f(c);
}

There is no need for you to reinvent the wheel. 没有必要重新发明轮子。 ::toupper and ::tolower take and return int , but their valid range is that of unsigned char . ::toupper::tolower接受并返回int ,但它们的有效范围是unsigned char Additionally, std::toupper and std::tolower both take char . 另外, std::toupperstd::tolower都采用char

Since it appears you are not using std::string , I'll try to keep it as close to your code as possible: 既然看起来你没有使用std::string ,我会尽量让它尽可能接近你的代码:

void upperList(LineEditor line)
{
    char c;
    // you do not have a begin() function??
    for(int i=0;i<100;i++)   //ensure iterator is at beginning of line
        line.left();           

    for(int i=0;i<100;i++)
    {
        c=line.at();
        c = std::toupper(c);
        line.at() = c; // assuming this returns a reference
        line.right(); 
    }
}

It becomes much easier if you modify your string class to behave more like the std::string class: 如果修改字符串类以使其更像std::string类,则会变得更加容易:

std::string line;
std::transform(line.begin(), line.end(), line.begin(), std::ptr_fun<int, int>(std::toupper));

Example

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM