Looking into this question about map of member function I'm observing an anomaly in the way to pass a pointer to member function into a std::any
.
I'm using the following snippet:
#include <any>
#include <iostream>
#include <map>
class VarCall {
public:
VarCall()
: calls({{"Alice", std::any(&VarCall::foo)},
{"Bob", std::any(&VarCall::bar)},
{"Charlie", std::any(&VarCall::baz)}}) {}
template <typename... Args>
void call(const std::string& what, Args... args) {
void (VarCall::*ptr)(Args...);
std::any a = ptr;
std::cout << a.type().name() << std::endl;
std::cout << calls[what].type().name() << std::endl;
// failed attempt to call
// this->*(std::any_cast<decltype(ptr)>(calls[what]))(args...);
}
public:
void foo() { std::cout << "foo()" << std::endl; }
void bar(const std::string& s) {
std::cout << "bar(" << s << ")" << std::endl;
}
void baz(int i) { std::cout << "baz(" << i << ")" << std::endl; }
std::map<std::string, std::any> calls;
};
int main() {
VarCall v;
void (VarCall::*ptr)(const std::string& s);
std::any a = ptr;
std::any b(&VarCall::bar);
std::cout << a.type().name() << std::endl;
std::cout << b.type().name() << std::endl;
// v.call("Alice");
v.call("Bob", "2");
// v.call("Charlie", 1);
return 0;
}
I'm expecting to have the following output:
M7VarCallFvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE
M7VarCallFvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE
M7VarCallFvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE
M7VarCallFvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE
but get
M7VarCallFvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE
M7VarCallFvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE
M7VarCallFvPKcE
M7VarCallFvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE
When initializing the std::any inside the VarCall()
initializer list, I'm getting a different signature.
What is happening?
Is there a way to get the expected output?
The final goal, as indicated in the original question from @merula, if to be able to call the member function, for instance with: std::any_cast<std::add_pointer_t<void(Args ...)>>(calls[what])(args...);
inside call
member function.