http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54755
Bug #: 54755 Summary: Template instantiation confused by actual template argument definitions before and after template definition Classification: Unclassified Product: gcc Version: 4.6.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: e678...@yahoo.co.uk The following code:- // --------------------------------------------- #include <iostream> // Before void Function ( int ) { std::cout << "int\n"; } void Function ( long ) { std::cout << "long\n"; } template <class x> struct TemplateClass { x Variable; void MemberFunction() { Function(Variable); } }; // After void Function ( float ) { std::cout << "float\n"; } int main ( int, char** ) { TemplateClass<int> I; I.MemberFunction(); TemplateClass<long> L; L.MemberFunction(); TemplateClass<float> F; F.MemberFunction(); } // --------------------------------------------- gives the compiler error:- error: call of overloaded 'Function(float&)' is ambiguous However, if all definitions of Function are in the "Before" block, and none in "After" it works. If all definitions are in the "After" block, and none in the "Before" code, it also works. If the int version of Function is in the "Before" code and the others in "After" all instantiations of the template use the int version because of implicit type conversion. This looks like a bug in the symbol lookup. All overloaded versions of Function can be found if they are either before or after the definition of the template that happens to use them, but only if they are all defined together. Separate the definitions before and after the template definition and it goes wrong. Note: iostream output has only been used in the example to illustrate the bug using std output. The code can be further simplified by removing iostream and the same thing happens.