This doesn't appear to be the case in release builds on VC.net. Based on the following -
Another explanation can be that it's a single function pointer, but not directly to the member function.
typedef void (a::*amemfun)();
amemfun e = a::fun;
The relevant call in main is -
00401006 mov dword ptr [ebp-4],offset a::fun (401020h)
0040100D lea ecx,[ebp-5]
00401010 call dword ptr [ebp-4]
The member function begins at 401020h -
So it's not a jump into a table.
00401020 push ebp
Altering fun to a virtual function produces the code -
at 401060h is (the virtual table) -
0040100E mov dword ptr [ebp-4],offset `vcall' (401060h)
00401015 lea ecx,[ebp-8]
00401018 call dword ptr [ebp-4]
which then jumps to the correct function.
00401060 mov eax,dword ptr [ecx]
00401062 jmp dword ptr [eax]
So based on this it would appear that it is determined at compile time whether the function pointer is to be used on non virtual functions on VC.net.