1
votes

public/Interface.h

#pragma once

template <typename T>
class BaseInterface {
public:
    virtual void foo() = 0;
};

private/Base.h

#pragma once
#include "../public/Interface.h"

template <typename T>
class Base : public BaseInterface<T> {
public:
   virtual void foo() override;
};

template <typename T>
inline void Base<T>::foo() {
}

main.cpp

#include <iostream>
#include <memory>
#include "public/Interface.h"

int main() {
    auto base = std::make_shared< BaseInterface<std::string> >();
    base->foo();
    return 0;
}    

Getting this error:

/usr/include/c++/5/ext/new_allocator.h:120:4: error: invalid new-expression of abstract class type ‘BaseInterface<std::__cxx11::basic_string<char> >’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }

AbstractPureVirtual/public/Interface.h:4:7: note:   because the following    virtual functions are pure within ‘BaseInterface<std::__cxx11::basic_string<char> >’:
 class BaseInterface {

AbstractPureVirtual/public/Interface.h:6:17: note:  void BaseInterface<T>::foo() [with T = std::__cxx11::basic_string<char>]
virtual void foo() = 0;

I get this error though I have overridden the pure virtual method in the Derived Class and seems like it is expected as its a template class. If I need to do something similar, how should I go about implementing this?

2
No, that has nothing to do with the derived class -- the compiler doesn't even know about private/Base.h when compiling main.cpp - L. F.
Differently phrased question with essentially the same answer. - 1201ProgramAlarm
Did you mean std::make_shared< Base<std::string>>() ? How the compiler would know which derived class to call to construct the interface class ? - Jarod42

2 Answers

1
votes

make_shared creates an object of exactly the class you specified. It is unable to know its derived classes, so make_shared< BaseInterface<std::string> >() essentially invokes new BaseInterface<std::string>, and creating object of an abstract class is not allowed. This has nothing to do with the templates; the error is still there if you replace them with ordinary classes.

0
votes
auto base = std::make_shared< BaseInterface<std::string> >();

you tried to create a concrete object of type BaseInterface<std::string> here. I suspect you want:

auto base = std::make_shared< Base<std::string> >();

or maybe

std::shared_ptr< BaseInterface<std::string> > base = std::make_shared< Base<std::string> >();