0

I have a simple code as below:

int global1(int x)
{
 return x * 5;
}

int global2(int x)
{
 return x + 5;
}

struct some_struct {
  int a;

  int foo1(int x)
  {
     return x * a;
  }

  int foo2(int x)
  {
     return x + a;
  }

  int bar1(int x, bool a)
  {
     auto func = a ? global1 : global2; // works
     // auto func = a ? &global1 : &global2; // also works

     return func(x);
  }

  int problem_function(int x, bool a) // It is my question
  {
     auto func = a ? foo1 : foo2; // gives error
     // auto func = a ? &foo1 : &foo2; // also gives error
     // auto func = a ? &this->foo1 : &this->foo2; // also gives error

     return func(x);
  }
};

It is a very simplified form of the real code. I have no way to carry function on the outside like how I did in this with global1() & global2().

I want to call one of the functions in the struct, but using a pointer to a function, but it gives an error.

Note: I can't use if..else because in the real code it doesn't return func(x). In the real code, I use func(x) as a condition for a function in a loop (I am not joking, it's literaly what I said).

A part from the real code:

void* find_first(ExprToken* (*cond)(bool (*)(ExprToken*))) {...} // yeah

I know if I want to call a function of a struct, I have to tell the compiler which variable (struct) I am using, but how?

Does C++ even support a function pointer in a struct?

Sorry for the complexity, sometimes I forget what the real code is actually doing.

4
  • Non-member functions and member functions are two very different things. The difference, of course, is that member functions needs an object to be called with, which non-member functions doesn't. There's plenty of information about this all over the Internet, including quite a lot on this site alone. Use your favorite search engine and search for e.g. c++ call pointer to member function. Commented May 4, 2024 at 22:12
  • And regarding that snippet from the "real" code, you can't use it for member functions, that's just not possible. You need to change the implementation of your design. Either to use std::function together with std::bind or lambdas; Or use templates (again with std::bind or lambdas), which is how the C++ standard library handles all its callable objects., Commented May 4, 2024 at 22:14
  • Thanks @Some programmer dude i found it on some website Commented May 4, 2024 at 22:21
  • "I can't use if..else because in the real code it doesn't return func(x)." -- I don't buy this. Mostly because you could write a function that returns func(x) and use that new function in place of the loop conditional. Break your messy functions into smaller pieces, and perceived problems like this tend to vanish. A few type aliases could also help. Commented May 5, 2024 at 1:36

2 Answers 2

2

you should set the function pointer to the method like that

auto func = a ? &some_struct::foo1 : &some_struct::foo2;

now you refer to the function of the struct and not of the object.

For call it, now you must use this syntax:

(this->*func)(x);

it mean "I call the function stored at adress of func and pass it the parameter x"

NB: In C++ avoid pointer to function like (*ptr)(void), it better to use the functional include which give you the syntax:

std::function<returnType(parameterType1, parameterType2, ..., parameterTypeN>
Sign up to request clarification or add additional context in comments.

1 Comment

"Better to use std::function" - not always, it comes at a price (there's a performance overhead)
1

Resource: https://public.websites.umich.edu/~eecs381/handouts/Pointers_to_memberfuncs.pdf

I found the answer on the internet and I wanted to share it under this question.

Answer:

  int problem_function(int x, bool a) // It is my question
  {
     auto func = a ? &some_struct::foo1 : &some_struct::foo2;

     return (*this).*func(x);
  }

2 Comments

You might want to look at this for alternative (syntactic) options. stackoverflow.com/a/63484420/4706785
Use (this->*func)(x) instead of (*this).*func(x)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.