I wrote the following code that hiding of member function templates.
#include <iostream> struct A { template<int> void func() { std::cout<<"Function tamplate of A"<<std::endl; } }; struct B : A { template<char> void func() { std::cout<<"Function tamplate of B"<<std::endl; } using A::func; }; int main() { B().func<0>(); }
This program working in in Clang compiler. Live demo Clang
But, GCC compiler give an ambiguity error.Live demo GCC
source_file.cpp: In function ‘int main()’: source_file.cpp:22:17: error: call of overloaded ‘func()’ is ambiguous B().func<0>();
So, Which compiler is correct?
The term member template refers to both member function templates and nested class templates. Member function templates are function templates that are members of a class or class template. Member functions can be function templates in several contexts.
No, template member functions cannot be virtual.
Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class. In this case the compiler generates a member function for each (unique) template type. As before, the compiler will favour a non-template overload of a member function.
Member functions of class templates (C++ only) You may define a template member function outside of its class template definition. The overloaded addition operator has been defined outside of class X . The statement a + 'z' is equivalent to a. operator+('z') .
Regarding the example in the OP: as pointed out to me by W.F., what matters here is that those are member function templates. You added a using declaration, which specifies ([namespace.udecl]/15):
When a using-declaration brings names from a base class into a derived class scope, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list, cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting).
Note how template parameters aren't accounted. And it is Clang that treated the code correctly by hiding the int
version.
On the other hand if one examines the example tobi303 suggested under your post, GCC is kinda in the right. This simply isn't specified to be resolved somehow.
For one, there's [temp.fct.spec]/3:
Trailing template arguments that can be deduced or obtained from default template-arguments may be omitted from the list of explicit template-arguments. [...] In contexts where deduction is done and fails, or in contexts where deduction is not done, if a template argument list is specified and it, along with any default template arguments, identifies a single function template specialization, then the template-id is an lvalue for the function template specialization.
The text in bold indicates that your program is well-formed only if the template argument we give nominates a single specialization. And ostensibly, it doesn't, since according to [temp.arg.nontype]/1:
A template-argument for a non-type, non-template template-parameter shall be one of:
- for a non-type template-parameter of integral or enumeration type, a converted constant expression of the type of the template-parameter;
And 0 fits both overloads as a converted constant expression. On account of there not being any ICS ranking for template arguments, this is ambiguous.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With