와 함께 작동하지 않습니다C++ 포인터 - 투 - 방법 템플릿 공제는 86을 대상으로 할 때 컴파일,하지만이 샘플 코드를 가지고 64
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 비트로 변경 될 수 있으며 오류 메시지에 표시된 서명에 표시되지 않는 유일한 사항은 호출 규칙입니다. 분명히, there is a unified calling convention for VC x64, whereas for x86 each calling convention is distinct. 그러나 그것이 문제가 되더라도, 나는 그것을 고치는 방법을 모른다.
도움말!
편집 : 정규식 (비 멤버) 함수 포인터를 사용하여이 작업을 시도했음을 언급해야합니다.
흠. 내 의혹을 확인해 주셔서 고마워요 (어떻게 그런 식으로 확인 했습니까? 저는 템플릿 인수를 디버깅하는 것이 매우 까다 롭습니다). 서명 규칙과 서명 규칙을 구분할 수있는 방법이 있습니까? 나는 Gobstopper 내에서 실제로 함수 포인터를 정의하기 위해'T'를 사용하지 않고 단순히 템플리트 전문화를 모호하게하는 수단으로 사용합니다. 또한 nitpick (OK, nitpick)은 아니지만 x64'__thiscall '에 대한 호출 규칙은 아니지만'__cdecl'과 호환 될 수 있습니까? – Cameron
사실, VC++의 32 비트 규칙은 "일반"기능의 경우 cdecl이고 멤버 기능의 경우이 항목입니다. 64 비트 Windows에서는 32 비트 환경에서 알려진 cdecl이나 thiscall이 아니지만 두 가지 모두에 대해 thiscall보다 더 많은 레지스터를 사용하는 것이 다릅니다. 더 많은 것을 알고 싶으면 http://www.agner.org/optimize/calling_conventions.pdf에 문의하십시오. 사용중인 모든 전화 규정이 나열되어 있습니다. –
아, 그리고 VS에서는'typid (T) .name()'을 사용하여 유형의 이름을 제공 할 수 있습니다 (템플릿 인수 일지라도). –