Reputation: 131
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)
. Hopefully I just don't understand how to pass functions as paremeters. The following are functions in my main cpp file
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
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.
Upvotes: 3
Views: 1063
Reputation: 15872
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
. Additionally, std::toupper
and std::tolower
both take char
.
Since it appears you are not using std::string
, I'll try to keep it as close to your code as possible:
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 line;
std::transform(line.begin(), line.end(), line.begin(), std::ptr_fun<int, int>(std::toupper));
Upvotes: 0
Reputation: 310980
the type of expression ToUpper(c) is char. So call
line.apply(ToUpper(c));
means to call function apply with argument of type char.
You should define the function as
void LineEditor::apply( char c, char f(char) )
{
*it=f(c);
}
Upvotes: 0
Reputation: 41625
The expression ToUpper(c)
calls the function, but when calling apply
you don't want to call that function immediately, so you need do say apply(ToUpper)
, since ToUpper
is the way to access the function itself.
Upvotes: 0
Reputation: 96810
When you call ToUpper
, it doesn't return the function, it returns the (supposed) character in its uppercase form.
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:
#include <functional>
line.apply(std::bind(ToUpper, c));
It requires the signature of apply
to be changed to:
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:
void LineEditor::apply(char (*f)(char), char c);
and call it as apply(ToUpper, c)
.
Upvotes: 2