Add using Base::operator[]; in the derived class to bring it into the scope:
struct Base
{
Base() = default;
Base(int value) {}
Base& operator[](int index) { return *this; }
Base& operator[](const char* index) { return *this; }
};
struct IntChild : public Base
{
using Base::operator[];
Base& operator[](const char* index) = delete;
};
IntChild test;
test[4] = 1; //works
Here is the relevant excerpt from using-declaration, which explains why after adding the using you can call the int
-overload in the base class:
In class definition
Using-declaration introduces a member of a base
class into the derived class definition, such as to expose a protected
member of base as public member of derived. In this case,
nested-name-specifier must name a base class of the one being defined.
If the name is the name of an overloaded member function of the base
class, all base class member functions with that name are introduced.
If the derived class already has a member with the same name,
parameter list, and qualifications, the derived class member hides or
overrides (doesn't conflict with) the member that is introduced from
the base class.
The question why it doesn't fall back to the base-class operator[](int)
without the using
is answered by unqualified name lookup (especially the point b) below):
Class definition
For a name used anywhere in class definition
(including base class specifiers and nested class definitions), except
inside a member function body, a default argument of a member
function, exception specification of a member function, or default
member initializer, where the member may belong to a nested class
whose definition is in the body of the enclosing class, the following
scopes are searched:
a) the body of the class in which the name is used until the point of
use
b) the entire body of its base class(es), recursing into their
bases when no declarations are found
So you don't go on to search for functions in the base class once you found one declaration in the derived class. Note that this also holds when you implement the derived class (not only when you =delete
it).