Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hiding of member function templates - Which compiler is correct?

Tags:

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?

like image 527
msc Avatar asked Oct 16 '17 11:10

msc


People also ask

What is member function template in C++?

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.

What is function template can a class member function template be virtual explain?

No, template member functions cannot be virtual.

What is a member template?

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.

How would you define member function outside the class template?

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') .


1 Answers

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.

like image 92
StoryTeller - Unslander Monica Avatar answered Sep 18 '22 14:09

StoryTeller - Unslander Monica