私はこのサンプルコードを持っています:
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;
}
これは で問題なくコンパイルされg++
ます。VC10 でも問題なくコンパイルできますが、64 ビット プラットフォーム用にビルドする場合のみです。32 ビット プラットフォーム用にビルドすると、次のコンパイル エラーが発生します。
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> ]
このエラーは、特殊化されていないバージョンの Gobstopper が使用されていることを示してSignature
いint (void)
ます。Signature
しかし、エラーはそれが であることも明確に示していますint (void)
。では、エラーはどこから来るのでしょうか? どうすれば修正できますか?
32 ビットから 64 ビットに変更され、エラー メッセージに表示される署名に表示されない可能性がある唯一のことは、呼び出し規約です。どうやら、VC x64 には統一された呼び出し規約がありますが、x86 ではそれぞれの呼び出し規約が異なります。しかし、それが問題だとしても、それを修正する方法がわかりません。
編集:通常の(非メンバー)関数ポインターでこれを試したところ、うまくいきました。