将函数作为参数传递 CPP

3

我正试图在我的主程序中调用一个类函数,它将一个函数作为其参数,并将该函数应用于一个私有列表。我得到了错误信息invalid conversion from char to char (*f)(char)。希望我只是不理解如何将函数作为参数传递。以下是我的主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
}
}

这是应用成员函数

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

此外,如果没有明显的提示,我尝试使用cctypes中的toupper和tolower函数,但它们接受并返回整数。

我尝试使用cctypes toupper和tolower,但它们接受并返回整数。char可以隐式转换为int,或者您可以使用std :: toupper / std :: tolower。您的ToUpper版本非常低效。 - Zac Howland
是的哈哈,似乎上面的代码直接忽略了隐式转换。但是有了答案中的代码,我很容易就实现了这些,谢谢! - CChiste
4个回答

2
当你调用 ToUpper 时,它不会返回函数本身,而是返回其大写形式的(假定的)字符。
另一个原因是你不能在函数指针的签名中创建参数。参数区域只指定函数所需的类型。这...
char (*f)(char c);
//        ^^^^^^

因此,这是错误的。
解决方案:
使用 std::function 并将其绑定到一个参数上:std::bind
#include <functional>

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

需要将apply的签名更改为:

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

如果您无法完成此操作,您可以让apply接受第二个参数作为参数:

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

然后将其称为apply(ToUpper, c)


0

ToUpper(c)表达式的类型是char。因此调用

line.apply(ToUpper(c));

意味着使用类型为char的参数调用apply函数。

您应该将函数定义为

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

你没有在 apply 函数中定义 it - Zac Howland

0

没有必要重新发明轮子。::toupper::tolower接受并返回int,但其有效范围是unsigned char的范围。此外,std::toupperstd::tolower都接受char

由于您似乎没有使用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(); 
    }
}

如果你修改你的字符串类,让它更像 std::string 类,那么这将变得更加容易:

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

示例


原始代码只是粗略地拼凑在一起哈哈,现在添加了一些更好的功能和效率 :) 谢谢您的回复! - CChiste

0
表达式 ToUpper(c) 调用了函数,但调用 apply 时不想立即调用该函数,因此需要写成 apply(ToUpper)。因为ToUpper 是访问函数本身的方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接