Is it possible to get the address of the first member function of a class in c++?
Suppose I have the following code
class A {
public:
A() {};
int foo()
{
cout << "bar" << endl;
return 0;
}
};
int main()
{
A().xxx(); //[2]
}
If I guarantee that there is only one public non-static member function
, is there a way to call it at [2] without caring what its name is?
I know this can be done via reflection, but using a reflection library adds compilation and runtime overhead, are there native methods (even for non-portable hacks) that do this?
Some additional notes:
1.foo()
may have different types and different numbers of formal arguments, and the foo()
function will change frequently, and the interface of each given foo() is fixed, so I can't think of a generic xxx() function (or function template) to easily forward these arguments as this answer said.
2.I thought there would be a hacking method to touch the actual address of a member function by its address and then to call it.
I only asked this question out of curiosity, and now I know
member functions aren't normally implemented as part of the class, they're really global functions with a hidden this parameter, it's not possible to do get the first method of the class at runtime
What I want to achieve is something like this
Disclaimer: This answer is just an extension to @463035818_is_not_a_number's answer.
In order to handle multiple number of arguments for several classes, you could make use of variadic templates and perfect forwarding.
Here is an example with two classes A
and B
both implementing such an xxx()
member function:
struct A
{
int foo()
{
std::cout << "bar\n";
return 42;
}
template <typename... Ts>
void xxx(Ts&& ... ts)
{
foo(std::forward<Ts>(ts)...);
}
};
struct B
{
void other_foo(const char * arg)
{
std::cout << arg << '\n';
}
template <typename... Ts>
void xxx(Ts&& ... ts)
{
other_foo(std::forward<Ts>(ts)...);
}
};
Which could be used like:
int main()
{
A().xxx();
B().xxx("baz");
return 0;
}
Note: This would still require to change your main depending on the arguments the target function accepts.
Note 2: I used a common return type for all xxx()
functions (which is void
). If you want to also handle different return types, maybe you could add a second (in the first position) template parameter for that purpose. But then it would make the calls in the main()
even more specific. It would possibly make the whole process pointless since the call would not look "generic" anymore.
Here is an example with templated return types as well.