Hello! I have FreeBSD 8.0-BETA4. Why this #include <iostream> template <typename T, unsigned int (T::*)() const> class TSizeEnabler { public: typedef T TClass; }; template <typename X> unsigned int GetAllSize(const X &Var) { return sizeof(Var); } template <typename X> unsigned int GetAllSize(const typename TSizeEnabler<X, &X::CalcMySize>::TClass &Var) { return Var.CalcMySize(); } template <typename T> class THash { public: T Var; unsigned int CalcMySize() const { return 42 + GetAllSize<T>(Var); } }; int main() { int a; THash<int> b; std::cout << GetAllSize<int>(a) << std::endl; std::cout << GetAllSize< THash<int> >(b) << std::endl; return 0; } works well at gcc 3.4.6 but fails at gcc 4.2.1 and gcc 4.5.0.20091008 with these messages: gcc 4.5.0.2009100 output: %g++45 -std=c++0x main.cpp main.cpp: In function 'int main()': main.cpp:24:46: error: call of overloaded 'GetAllSize(THash<int>&)' is ambiguous main.cpp:6:36: note: candidates are: unsigned int GetAllSize(const X&) [with X = THash<int>] main.cpp:8:36: note: unsigned int GetAllSize(const typename TSizeEnabler<X, (& X::CalcMySize)>::TClass&) [with X = THash<int>, typename TSizeEnabler<X, (& X::CalcMySize)>::TClass = THash<int>] % And gcc 4.2.1 output: %g++ main.cpp main.cpp: In function 'int main()': main.cpp:23: error: call of overloaded 'GetAllSize(THash<int>&)' is ambiguous main.cpp:5: note: candidates are: unsigned int GetAllSize(const X&) [with X = THash<int>] main.cpp:7: note: unsigned int GetAllSize(const typename TSizeEnabler<X, (& X::CalcMySize)>::TClass&) [with X = THash<int>] % And how i can fix it the problem? Thanks.
Slightly reduced: template <typename T, int (T::*)() const> struct TSizeEnabler { typedef T TClass; }; template <typename X> int GetAllSize(const X &Var) { return sizeof(Var); } template <typename X> int GetAllSize(const typename TSizeEnabler<X, &X::func>::TClass &Var) { return Var.func(); } struct H { int func() const; }; int main() { H b; return GetAllSize< H >(b); } I think you're right that this is a bug. As a workaround you might be able to remove GetAllSize(const X &Var) from the overload set for the case when X::CalcMySize exists.
Subject: Bug 41703 Author: jason Date: Fri Nov 6 03:32:55 2009 New Revision: 153957 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153957 Log: PR c++/41703 * pt.c (check_undeduced_parms): New subroutine of... (more_specialized_fn): ...here. Undeduced template parms can make a template less specialized than another. Added: trunk/gcc/testsuite/g++.dg/template/partial6.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c trunk/gcc/testsuite/ChangeLog
Fixed for 4.5.