I've got this sample code:
struct A
{
int foo() { return 27; }
};
template<typename T>
struct Gobstopper
{
};
template<>
struct Gobstopper<int(void)>
{
Gobstopper(int, int) { } // To differentiate from general Gobstopper template
};
template<typename ClassType, typename Signature>
void DeduceMethodSignature(Signature ClassType::* method, ClassType& instance)
{
// If Signature is int(), Gobstopper<> should resolve to the specialized one.
// But it only does on x64!
Gobstopper<Signature>(1, 2);
}
int main(int argc, char** argv)
{
A a;
DeduceMethodSignature(&A::foo, a);
return 0;
}
This compiles fine with g++
. It also compiles fine with VC10, but only when building for the 64-bit platform. When I build for the 32-bit platform, I get this compile error:
error C2661: 'Gobstopper<T>::Gobstopper' : no overloaded function takes 2 arguments
1> with
1> [
1> T=int (void)
1> ]
1> c:\...\test.cpp(26) : see reference to function template instantiation 'void DeduceMethodSignature<A,int(void)>(Signature (__thiscall A::* ),ClassType &)' being compiled
1> with
1> [
1> Signature=int (void),
1> ClassType=A
1> ]
The error indicates that the non-specialized version of Gobstopper is being used, which must mean the Signature
is something other that int (void)
. But the error also clearly says that Signature
is int (void)
. So where does the error come from? And how can I fix it?
The only thing I can think of that might change from 32-bit to 64-bit and not show up in the signature displayed in the error message is the calling convention; apparently, there is a unified calling convention for VC x64, whereas for x86 each calling convention is distinct. But even if that's the problem, I have no idea how to fix it.
Edit: I should mention that I tried this with regular (non-member) function pointers, and that worked fine.