Weird name resolution

Given:
1
2
3
4
5
6
7
8
9
10
11
12
class Entry{
protected:
    virtual void to_DirectoryEntry(DirectoryEntry &) const = 0;
public:
    DirectoryEntry to_DirectoryEntry() const;
};

class Directory : public Entry{
protected:
    void to_DirectoryEntry(DirectoryEntry &) const override;
public:
};
This:
1
2
auto p = std::make_unique<Directory>();
/*...*/ = p->to_DirectoryEntry();
is rejected with
error C2660: 'Directory::to_DirectoryEntry': function does not take 0 arguments
see declaration of 'Directory::to_DirectoryEntry' [points to line 10]

What's going on here?
Last edited on
I've seen this before. Apparently the compiler stops looking when it finds a function with a matching name in the derived class so it doesn't look to see in the base class if there is a better match.

To fix this you can write:

1
2
3
4
5
6
class Directory : public Entry{
protected:
    void to_DirectoryEntry(DirectoryEntry &) const override;
public:
    using Entry::to_DirectoryEntry;
};
Last edited on
Core Guidelines:
C.138: Create an overload set for a derived class and its bases with using

Reason Without a using declaration, member functions in the derived class hide the entire inherited overload sets.

https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rh-using
Ugh. So dumb. Yeah, now I remember. I've done this at least once before. It's so counterintuitive.

Thanks.
Topic archived. No new replies allowed.