I have an hierarchy with an operator()
overloading like the following
class Base{
public:
virtual std::vector<float> operator()(const std::vector<float>& us) const {
// some implementation like
// return us;
}
virtual float operator()(float u) const = 0;
};
and a derived class
class Derived : public Base{
public:
float operator()(float u) const override {
return u;
}
};
The invocation code looks like the code below (assume, the GetAVectorOfFloats
second is indeed std::vector
of float
s).
Derived d;
auto [_, us] = GetAVectorOfFloats();
auto values = d(us);
However, the compiler (gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)) spits
error: no match for call to ‘(Derived) (std::vector&)’
I observe, that const std::vector<float>&
is not an option (but why?).
In case the code is more explicit
auto values = d.operator()(us);
the error becomes
error: cannot convert ‘std::vector< float>’ to ‘float’
Seems, like I’m missing something very basic? Can not I call the Base’s operator() or is there some special syntax I should use?
2
Answers
This is classic name hiding, nothing at all special about operator overloading:
When lookup for the name
operator()
is done inDerived
(because that’s the type ofd
) it findsfloat operator()(float u) const;
.Then name lookup terminates because the name has been found. There will not be any further lookup into the base class.
Solution is to make the other overload visible to name lookup in the scope of the derived class:
You encountered this problem because of name hiding.
You may see that if you overload neither of the operators (assuming they are not pure virtual), then both operators will work fine in the derived class.
Because you overloaded only one of the operators, the other effectively becomes hidden, as it is not directly a part of
Derived
.To overcome this problem, you can either overload both operators, or explicitly bring the
Base
class’ operators to scope: