Search code examples
c++oopinheritanceoverloadingabstract-class

Unable to call pure abstract base class overload


Why does the following code not compile and what can I do about it? Shouldn't it find the pure abstract method declared in the base class?

#include <string>

using namespace std::string_literals;

struct A
{
    virtual void func1(int) = 0;
    virtual void func1(std::string) = 0;
};

struct B : A
{
    void func1(int) override
    {
        func1("bla"s);
    }
};

struct C : B
{
    void func1(std::string) override
    {
    }
};

error C2664: 'void B::func1(int)': cannot convert argument 1 from 'std::string' to 'int'

Thanks in advance, Martin

Edit about the linker error!

If have three files:

file test.h

#include <string>

using namespace std::string_literals;

struct A
{
    virtual void func1(int) = 0;
    virtual void func1(std::string) = 0;
};

struct B : A
{
    void func1(int) override
    {
        A::func1("bla"s);
    }
};

struct C : B
{
    void func1(std::string) override;
};

file test.cpp

void C::func1(std::string)
{

}

file main.cpp

int main()
{
    C c;

    return 0;
}

This leads to

Error LNK2019 unresolved external symbol ""public: virtual void __thiscall A::func1(class std::basic_string,class std::allocator >)" (?func1@A@@UAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)" in Funktion ""public: virtual void __thiscall B::func1(int)"

I'm using visual C++ v140.

It works with using A::func1;. What is the difference?


Solution

  • B's implementation of func1 hides the other two overloads from A. You can import them back into B's interface by:

    struct B
    {
        using A::func1;
        /* ... */
    };
    

    In general, you can alternatively call a base class' overloads directly:

    void /*B::*/func1(int) override
    {
        A::func1("bla"s);
    }
    

    This will call exactly the version of the base class, though, not an overriding variant of, but in given case, A's variant of is pure virtual (i. e. does not exist), and thus we cannot apply this approach here.