1

Inheritance and template operator overloading

I don't understand why the operator in A<int> overshadows the operator in base. It has a different signature after all.

#include <iostream>

struct base {
  template <typename U>
  void operator()(U&& x) { std::cout << "base" << std::endl; }
};

template <typename T>
struct A: public base { };

template <>
struct A<int>: public base {
  void operator()() { std::cout << "A<int>" << std::endl; } // line 1
};

int main()
{
  A<double>()(1);
  A<int>()(1); // line 2
  A<int>()();  // line 3
}

Line 2 does not compile if line 1 is present.

Line 3 does not compile if line 1 is removed (obviously).

If I copy the operator template from base to A, everything works.

I expected the output to be:

base
base
A<int>
SU3
  • 5,064
  • 3
  • 35
  • 66
  • 1
    It's called *name hiding*. See e.g. http://stackoverflow.com/questions/1628768/why-does-an-overridden-function-in-the-derived-class-hide-other-overloads-of-the – Alan Stokes Jun 15 '16 at 21:42
  • You can resolve the issue by inserting `using base::operator();` in your class A. Be aware that accessibility is depending on where you insert your using declarations and that you can change accessibility in respect to the parent's one (e. g. make protected functions public by placing the using into the public section). – Aconcagua Jun 15 '16 at 21:55
  • And be aware that you cannot "unhide" a single function this way - either all overloads or none (exception: there is only one function with given name in the parent...). – Aconcagua Jun 15 '16 at 21:57

1 Answers1

3

The declaration of the operator in the derived class hides the name in the base class.
To solve the issue, it's a matter of a using declaration:

template <>
struct A<int>: public base {
    using base::operator();
    void operator()() { std::cout << "A<int>" << std::endl; }
};

And both of them will compile.

skypjack
  • 49,335
  • 19
  • 95
  • 187
  • Thanks, that works. Is the point of the `using declaration` being obligatory to prevent problems with multiple inheritance? Would there be a problem, if the standard specified that unless a `using declaration` is present, the function from the first listed parent class is used? – SU3 Jun 15 '16 at 21:48
  • Answered in a comment to the question: http://stackoverflow.com/a/1629074/2640636 Thanks @Alan Stokes – SU3 Jun 15 '16 at 21:58