2

In my search for a way to store CRTP objects in a container, I found the following question:

A polymorphic collection of Curiously Recurring Template Pattern (CRTP) in C++?

I tryied the marked solution

https://stackoverflow.com/a/24795227/5475431

but the compiler is complainings erros like:

no known conversion for argument 1 from ‘std::shared_ptr<DerivedA>’ to ‘const std::shared_ptr<BaseInterface>&’

here is my try:

#include <vector>
#include <memory>

struct BaseInterface {
    virtual ~BaseInterface() {}
    virtual double interface() = 0;
};

template <typename Derived>
class Base : BaseInterface {
public:
    double interface(){
        return static_cast<Derived*>(this)->implementation();
}
};

class DerivedA : public Base<DerivedA>{
public:
     double implementation(){ return 2.0;}
};

class DerivedB : public Base<DerivedB>{
public:
     double implementation(){ return 1.0;}
};


int main() {
    std::vector<std::shared_ptr<BaseInterface>> ar;
    ar.emplace_back(std::make_shared<DerivedA>());
return 0;
}

do you have any idea how to fix the compiler error, or how to solve the problem better? Thanks in advance

Mauri
  • 1,185
  • 1
  • 13
  • 21
  • 2
    Why do you need to mix CRTP and run-time polymorphism? – SergeyA Feb 12 '19 at 16:42
  • 7
    `class Base : BaseInterface` uses private inheritance, so pointers to classes that derive from `Base` aren't convertible to `BaseInterface*`. – François Andrieux Feb 12 '19 at 16:43
  • BTW when you paste an error message, it's _really_ useful to point out where in the code it occurred. The compiler will show _you_, so you should show us (line numbers are easy to break anyway, showing the location is better). – Useless Feb 12 '19 at 16:44
  • @FrançoisAndrieux first correct answer to the problem as stated. You should post an answer :) – SergeyA Feb 12 '19 at 16:44
  • @FrançoisAndrieux thank very much for your remark; the problem war private derivation – Mauri Feb 12 '19 at 16:47
  • @Useless the compiler is complaining the emplace_back and the I posted the error – Mauri Feb 12 '19 at 16:51

2 Answers2

6

Base should be an public inheritance of BaseInterface(and you also forgot return). Then ar.emplace_back(std::make_shared<DerivedA>()); well works:

DEMO

template <typename Derived>
class Base : public BaseInterface {
public:
    double interface(){
        return static_cast<Derived*>(this)->implementation();
    }
};
Hiroki
  • 2,780
  • 3
  • 12
  • 26
5

You're missing a return statement and Base should inherit from BaseInterfacepublically.

template <typename Derived>
struct Base : BaseInterface
{
    double interface() {
        return static_cast<Derived*>(this)->implementation();
    }
};

Live demo

But beware https://stackoverflow.com/a/24795059/5470596 <-- the answer the other OP should have accepted.

YSC
  • 38,212
  • 9
  • 96
  • 149