I am trying to pass parameters to a function pointer being passed as a parameter.
Code:
void Test(wchar_t* a, wchar_t* b)
{
// ...
}
void Test2(void(*Func)(wchar_t*, wchar_t*))
{
// ...
}
int main()
{
Test2(Test(L"Hello", L"Testing"));
return 0;
}
I am getting this error:
argument of type "void" is incompatible with parameter of type "void (*)(wchar_t *, wchar_t *)"
How do I fix this to accomplish what I'm trying to achieve?
Edit: Sorry for not being clear. What I'm actually trying to accomplish is inject a function into a child process and pass two parameters (wchar_t*, wchar_t*) so I can use them. But the main function can either be void or int argc, char** argv. So I accomplished what I'm trying to achieve by simply using global variables
You probably want to have something like
void Test2(void(*Func)(wchar_t*, wchar_t*),wchar_t* x, wchar_t* y)
{
(*Func)(x,y);
}
int main()
{
Test2(Test,L"Hello", L"Testing");
return 0;
}
instead.
As for your comment
How do i do this in C++ with templates?
I could think of
template<typename Param>
void Test2(void(*Func)(Param, Param), Param x, Param y) {
(*Func)(x,y);
}
void Test(wchar_t* a, wchar_t* b);
int main() {
Test2(Test,L"Hello", L"Testing");
return 0;
}
This should just work fine.
There are more than one way to fix tihs issue, however, let me just try to show why this error is occuring.
Every function has a type of value associated with it. This means, that every function evaluates to a value of some type. This is indicated by its return value.
For example:
int foo(/*whatever*/);
evaluates to an int. So foo(/*whatever*/) can be used anywhere an int is expected. For example like int a = b + foo(/*whatever*/).
Simlarly float bar(/*whatever*/); evaluates to a float, hence bar(/*whatever*/) can be used anywhere a float is expected. For example like float a = b + bar(/*whatever*/).
A function that returns void like void foobar(/*whatever*/) however, evaluates to void and cannot be used where a value of some type (say int, float, etc) is expected.
Now coming to code. This line in your main function has the issue:
int main()
{
Test2(Test(L"Hello", L"Testing")); /* Issue here */
return 0;
}
Here you are passing Test(L"Hello", L"Testing") as the argument to Test2. Now remember, that Test(/*whatever*/), evaluates to a void because Test returns a void.
So what you are doing in that line is something like
Test2(/*something that evaluates to a void*/);
However, Test2 expectes a void (*)(wchar_t*, wchar_t*), which is a pointer to a function that returns void, which is different from void.
So what is happening, is that the compiler is seeing that you are passing a void in a place where a void (*) (wchar_t*, wchar_t*) is expected, so it is correctly indicating that error.
There can be different ways to solve this issue which are mentioned in other answers.
Do I need to use C++ templates?
Of course, you can do that using C++ templates as it follows:
#include<utility>
// ...
template<typename F, typename... A>
void Test2(F &&f, A&&... a)
{
std::forward<F>(f)(std::forward<A>(a)...);
// ...
}
// ...
Test2(Test, L"Hello", L"Testing");
But you don't need them to do what you are trying to do.
#πάνταῥεῖ has already explained why in its answer.
Related
void print(string str,int a=0)
{
cout<<str;
}
int main()
{
string str="hello world";
print(str);
return 0;
}
why is the code working if I'am only passing one argument whereas the function needs two arguments
Whenever you have a function with a defaulted argument
void some_func(int a, int def = 0)
{
//something
}
The following call
some_func(42);
is converted into
some_func(42, 0);
And you can also call the function with two arguments, such as some_func(42, 1);
It works because you defined this int on a function declaration. The compiler knows that a =0 and is an int type. However if you lets say call this function like this:
print(str,10);
int a will have value of 10 instead of 0.
You are declaring function with one argument to have a default initial value, that is why you are able to call function without that argument.
if not passing that argument to function, its initial value that you declared, is used.
I have two functions with the same name but different return types. I want to run the function based on their third parameter. If the third parameter is true I want to run the first and If the parameter is false to run the second function. I was trying different things on my own because I couldn't find information online and I wasn't sure how is this called. Here is what I tried to do:
static int function(int a, int b, const bool=true);
static std::string function(int a, int b, const bool=false);
I would be grateful if someone can explain how to do this or at least give me a link to some information.
This solution is not about having two different functions but if you wanted the function to return a different type depending on the bool value using boost::any.
boost::any function(int a, int b, const bool c) {
std::string str = "Hello world!";
int num = 10;
if ( c ) {
return boost::any(num);
} else {
return boost::any(str);
}
}
This would use the third parameter in the function in order to decide which return you should do. Depending on how big function is this might be a worse solution but if you really wanted to use a boolean as a parameter I believe this should work.
Docs: Boost
Related question to this answer: Function which returns an unknown type
You can create a function template and add specializations for the different return types. Then you could use the bool argument as a template parameter:
template<bool>
auto function(int, int);
template<>
auto function<true>(int a, int b)
{
// ...
return int{};
}
template<>
auto function<false>(int a, int b)
{
// ...
return std::string{};
}
The functions would then be called like this:
int a = function<true>(1,2);
std::string b = function<false>(1,2);
Here's a demo.
Note the important caveat that the bool parameter must be known at compile time, and can't be a run time argument.
While this technique will work, do be aware that this will confuse a lot of c++ programmers. They usually expect a function to always return a particular type.
More relevant to your question; this is not actually going to make the code much more readable. Instead, having separate named functions is probably a more readable approach:
int int_function(int a, int b);
std::string str_function(int a, int b);
which could be called like this:
int a = int_function(1,2);
std::string b = str_function(1,2);
I have two functions with a little different functionality, so I can't make them as template functions.
int func64(__int64 a) {
return (int) a/2;
}
int func32(int a) {
return a--;
}
Depending on variable b64, I would like to call func64 or func32. I don't want check if b64 is true many times in my code, so I use pointers to functions.
void do_func(bool b64) {
typedef int (*pfunc32)(int);
typedef int (*pfunc64)(__int64);
pfunc32 call_func;
if (b64)
call_func = func64; //error C2440: '=' : cannot convert from 'int (__cdecl *)(__int64)' to 'pfunc32'
else
call_func = func32;
//...
call_func(6);
}
How can I avoid this error and cast call_func to pfunc32 or pfunc64?
The language requires all functions called through the same function pointer to have the same prototype.
Depending on what you want to achieve, you could use the pointer/cast aproach already mentioned (which satisfies this requirement at the loss of type safety) or pass a union instead:
union u32_64
{
__int64 i64;
int i32;
};
int func64(union u32_64 a) {
return (int) a.i64/2;
}
int func32(union u32_64 a) {
return --a.i32;
}
void do_func(bool b64) {
typedef int (*pfunc)(union u32_64);
pfunc call_func;
if (b64)
call_func = func64;
else
call_func = func32;
//...
union u32_64 u = { .i64 = 6 };
call_func(u);
}
Pass a void pointer and cast it in the function body.
Of course this means less compiler control if you use the wrong type; if you call func64 and pass an int to it the program will compile and produce wrong results without giving you any tip of what is going wrong.
int func64(void *a) {
__int64 b = *((__int64*) a);
return (int) b/2;
}
int func32(void *a) {
int b = *((int *) a)
return b-1;
}
I need to call func32() or func64() depending on flag b64
So do that:
void do_func(bool b64) {
if (b64)
func64(6);
else
func32(6);
}
Well, first of all, please note that function func32 is returning the input argument as is.
This is because with return a--, you are returning the value of a before decrementing it.
Perhaps you meant to return a-1 instead?
In any case, you can simply declare this function as int func32(__int64 a).
This way, it will have the same prototype as function func64, but will work exactly as before.
BTW, calling a function through a pointer might be more "expensive" than a simple branch operation, so depending on your application, you might be better off with a simple if/else conditional statement...
Make a wrapper for func64:
int func64_as_32(int a) {
return func64(a);
}
Now you can assign either func32 or func64_as_32 to call_func since they have the same signature. The value you pass in, 6, has type int so passing it to func64_as_32 has the same effect as passing it directly to func64.
If you have call sites where you pass in a value of type __int64 then you'd do it the other way around, wrap func32.
As bool in C++ converts to int ( true => 1, false => 0 ) you can use b64 as array index. So take SJuan76's advice, convert your functions prototype to int f(void*) and put them into array int (*array_fun[2])(void* x); . You can call these functions then like that :
int p = 6;
array_fun[b64](&p);
I'm sure this has been asked before, but it's just hard to search for...
So, what I've got is a function that accepts a function pointer. This function pointer has, say, 3 arguments. So, I want to pass to another function, the same pointer, but with 2 arguments filled in.
So, something like this:
int func1 (int (*funcptr)(int, int, int)) {
return func2(funcptr(,8,9));
}
int func2 (int (*funcptr)(int)) {
return (*funcptr)(2);
}
EDIT:
Ok so I got this now with the usage of a lambda
int func2(int (*funcptr2)(int)) {
return (*funcptr2)(2);
}
int func1(int (*funcptr1)(int, int, int)) {
return func2(
[funcptr1](int i)->int {
return (*funcptr1)(i,8,9);
}
);
}
But it's giving me
"cannot convert func1(int (*)(int, int, int))::<lambda(int)> to int (*)(int) for argument 1 to int func2(int (*)(int))"
This is called a lambda, and you can do it with newer C++ versions, std::bind, boost::bind or boost::function.
To answer your updated question, a lambda which captures variables (as your lambda does with funcptr1) cannot be converted to a function pointer. Intuitively this makes sense since your lambda must store this captured variable per lambda; whereas there is no way to do that with a function pointer.
The best solution is probably to take an argument of type std::function, which is a wrapper for any callable type:
int func2(std::function<int(int)> funcptr2) {
return funcptr2(2);
}
int func1(std::function<int(int,int,int)> funcptr1) {
return func2(
[funcptr1](int i)->int {
return funcptr1(i,8,9);
}
);
}
You can also use templates to make your functions work for any callable type:
template <typename F>
int func2(F funcptr2) {
return funcptr2(2);
}
template <typename F>
int func1(F funcptr1) {
return func2(
[funcptr1](int i)->int {
return funcptr1(i,8,9);
}
);
}
In C, you can't. You would have to pass the function pointer, and the two arguments.
In C++, you can use std::bind (or boost::bind in older versions) to achieve this.
I need to pass something like a pointer that takes anything as a function parameter. You know, something without any predefined type or a type that can take anything like this:
void MyFunc( *pointer );
And then use it like:
char * x = "YAY!";
MyFunc(x);
int y = 10;
MyFunc(&y);
MyObj *b = new MyObj();
MyFunc(b);
And I don't want to use templates because I am mostly using C in my project.
Is there anything that can be used here except a function macro?
In C++, Boost.Any will let you do this in a type-safe way:
void func(boost::any const &x)
{
// any_cast a reference and it
// will throw if x is not an int.
int i = any_cast<int>(x);
// any_cast a pointer and it will
// return a null pointer if x is not an int.
int const *p = any_cast<int>(&x);
}
// pass in whatever you want.
func(123);
func("123");
In C, you would use a void pointer:
void func(void const *x)
{
// it's up to you to ensure x points to an int. if
// it's not, it might crash or it might silently appear
// to work. nothing is checked for you!
int i = *(int const*)x;
}
// pass in whatever you want.
int i = 123;
func(&i);
func("123");
You seem adverse to it but I'll recommend it anyway: if you're using C++, embrace it. Don't be afraid of templates. Things like Boost.Any and void pointers have a place in C++, but it is very small.
Update:
Well , I am making a small signals - slots - connections library to be
used with my gui toolkit. So that I can get rid of the Ugly WNDPROC. I
need these pointers for the connections.
If you need multi-target signals, Boost.Signals already provides a full and tested signals/slots implementation. You can use Boost.Bind (or std::bind, if you've got a C++0x compiler) to connect member functions:
struct button
{
boost::signal<void(button&)> on_click;
}
struct my_window
{
button b;
my_window()
{
b.on_click.connect(std::bind(&my_window::handle_click,
this, std::placeholders::_1));
}
void handle_click(button &b)
{
}
void simulate_click()
{
b.on_click(b);
}
};
If you only want a simple callback, Boost.Function (or std::function if you've got a C++0x compiler) will work well:
struct button
{
std::function<void(button&)> on_click;
}
struct my_window
{
button b;
my_window()
{
b.on_click = std::bind(&my_window::handle_click,
this, std::placeholders::_1);
}
void handle_click(button &b)
{
}
void simulate_click()
{
b.on_click(b);
}
};
You can use a function that takes a void*, but you must be aware of the pointer types that are not compatible with void*:
pointers to functions:
void MyFunc(void*);
MyFunc(&MyFunc); // WRONG
pointers to members:
void MyFunc(void*);
struct A { int x; };
MyFunc(&A::x); // WRONG
While these pointers are not compatible with void* (even with casting, on some compilers), they are themselves data. So you can pass a pointer to the pointer:
void MyFunc(void*);
void (*pfn)(void*) = &MyFunc;
MyFunc(&pfn); // ok
struct A { int x; };
int A::*px = &A::x;
MyFunc(&px); // ok
You can define the method as taking one void * argument. Of course, at that point, it's up to you to figure out what to do with the data (as far as accessing it or casting it.)
void MyFunc(void * ptr);
You could use:
void MyFunc( void* p){}
int g = 10;
MyFunc( (void*)&g );
void * is the way to do it. You can assign any pointer type to and from a void *. But to use the pointer in the called function, you'll have to know the type so you can create an appropriate local pointer or cast appropriately. You can encode a limited set of types as enum symbols, and perhaps use a switch to select type-specific behavior. But without a specific purpose or use-case, you might end up chasing your tail in a quest for generality for which C was never intended.
Another way would be to make a union to contain all the various types you know are needed.
typedef union {
int i;
char c;
float f;
} vartype;
Then if the value can carry around its own type-identifier, it becomes a tag-union or variant-record.
typedef struct {
enum type { INT, CHAR, FLOAT } type;
vartype var;
} varrec;