About function pointer as map's value


Hello everyone,
like this code

class A {
public:
A() {}
void show() { }
int a;
};

void* CreateA() {
return new A();
}

int main() {
map<string, void*> mp = {
{"A",&CreateA}
};

A* a = (A*)mp["A"](); // wrong at this line
a->a = 10;
a->show();
return 0;
}

My understanding is that the address of the function is stored in the map, so calling mp["A"]() should be equivalent to CreateA(), but the compiler cannot compile it.Why ?

Thanks.
void* can't be used to point to functions.
The code will compile if you change
 
map<string, void*>
to
 
map<string, void*(*)()>

void*(*)() is what's known as a function pointer type.
A pointer to a function that takes no arguments and returns a void*.
Last edited on
Do you mean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <string>
#include <map>
#include <iostream>

class A {
public:
	A() {}
	void show() { std::cout << a << '\n'; }
	int a {};
};

void* CreateA() {
	return new A();
}

int main() {
	std::map<std::string, void*> mp {{"A", &CreateA} };

	const auto a { (A*)((void* (*)())mp["A"])() };

	a->a = 10;
	a->show();
}


which displays:


10


or:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <string>
#include <map>
#include <iostream>

class A {
public:
	A() {}
	void show() { std::cout << a << '\n'; }
	int a {};
};

void* CreateA() {
	return new A();
}

int main() {
	std::map<std::string, void*(*)()> mp {{"A", &CreateA}};

	const auto a { (A*)mp["A"]() };

	a->a = 10;
	a->show();
}


or using c++ cast (rather than c):

1
2
3
4
5
6
7
8
int main() {
	std::map<std::string, void*(*)()> mp {{"A", &CreateA}};

	const auto a { reinterpret_cast<A*>(mp["A"]()) };

	a->a = 10;
	a->show();
}

Last edited on
Thanks for everyone
seeplus, your first program doesn't seem to compile using GCC and Clang.

I think the problem is that there is no implicit conversion from function pointers to void*. Doing an explicit cast seems to work but not sure if it's guaranteed by the standard.
Last edited on
> Doing an explicit cast seems to work but not sure if it's guaranteed by the standard.

It is not guaranteed by the standard; but
8) On some implementations (in particular, on any POSIX compatible system as required by dlsym), a function pointer can be converted to void* or any other object pointer, or vice versa. If the implementation supports conversion in both directions, conversion to the original type yields the original value, otherwise the resulting pointer cannot be dereferenced or called safely.
https://en.cppreference.com/w/cpp/language/reinterpret_cast
Topic archived. No new replies allowed.