Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheritance and member-function templates overloading

I try to compile the following code with clang (version 3.0), but it gives me this error

error: no matching member function for call to 'a'

in the call __a.a<0>(). Then I try with g++ (version 4.2.1) and it compiles and works as expected (print out 1 2).

#include <iostream>

struct A {
  template <int> int a() { return 1; }
};

struct B: A {
  using A::a;
  template <int,int> int a() { return 2; }
};

int main(int, char **) {
  B __a;
  std::cout << __a.a<0>() << " "  << __a.a<0,0>() << std::endl;
  return 0;
}

I try to look to the standard but I have not found anything that explains which is the correct behavior of compiler. Now, my question is which is the correct behavior, and if clang works correctly, how I can modify my code to work as expected?

like image 689
mattia.penati Avatar asked Aug 11 '26 05:08

mattia.penati


1 Answers

Digging through both the C++03 and C++11 standard, it doesn't look good for your code to be valid and well-formed. C++03 seems to have allowed this, while a change in the wording of the C++11 standard seems to have disallowed this.

§7.3.3 [namespace.udecl] (Both standards)

p12 (C++03) When a using-declaration brings names from a base class into a derived class scope, member functions in the derived class override and/or hide member functions with the same name and parameter types in a base class (rather than conflicting).

Note that this wording doesn't mention any member function templates.

p15 (C++11) 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 (8.3.5), cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting).

Note the mentioning of member function templates in the new wording. Also note, that the list that determines if a derived class member overrides / hides a base class member doesn't mention the template-parameter-list of the member function template as an identifying point, it is being ignored for this purpose.

I might be interpreting this completely wrong, but it seems Clang is the conforming compiler here, and GCC aswell as MSVC10 are non-conforming according to the new wording.

like image 185
Xeo Avatar answered Aug 13 '26 19:08

Xeo