-1

I am trying to implement visitor pattern for my project similar to this snippet. But the code is spitting out a runtime error. The error it prints is bad_weak_ptr . The code itself seems correct and I can't find any issue with the design pattern. This probably is happening due to smart pointers.

template<class T> class Beignet;
template<class T> class Cruller;

template<class T>
class PastryVisitor {
    public:
    virtual T visitBeignet(shared_ptr<Beignet<T>> beignet) = 0;
    virtual T visitCruller(shared_ptr<Cruller<T>> cruller) = 0;
};

template<class T>
class Pastry {
    public:
    virtual T accept(shared_ptr<PastryVisitor<T>> visitor) = 0;
};

template<class T>
class Beignet : public Pastry<T>, enable_shared_from_this<Beignet<T>> {
    
    public:
    T accept(shared_ptr<PastryVisitor<T>> visitor) override {
        return visitor->visitBeignet( this->shared_from_this() );
    }
};

template<class T>
class Cruller : public Pastry<T>, enable_shared_from_this<Pastry<T>> {
    
    public:
    T accept(shared_ptr<PastryVisitor<T>> visitor) override {
        return visitor->visitCruller( this->shared_from_this() );
    }
};

class PastryPrinter : public PastryVisitor<string>, enable_shared_from_this<PastryPrinter> {

    public:
    string print(shared_ptr<Pastry<string>> pastry) {
        return pastry->accept( shared_from_this() );
    }

    string visitBeignet(shared_ptr<Beignet<string>> beignet) override {
        return "Beignet";
    }

    string visitCruller(shared_ptr<Cruller<string>> cruller) override {
        return "Cruller";
    }

};

int main() {
    auto pastry = make_shared<PastryPrinter>();
    shared_ptr<Pastry<string>> chocolateBeignet = make_shared<Beignet<string>>();
    pastry->print(chocolateBeignet);
}
Sid Sharma
  • 51
  • 1
  • 9
  • 2
    Correct [all of the compiler errors](https://godbolt.org/z/3cov8d755) and your question will be in a much better position vis-a-vis getting answered. – user4581301 Feb 03 '22 at 00:43

1 Answers1

2

You inherit std::enable_shared_from_this privately. It must be inherited publicly to work:

class Cruller : public Pastry<T>, public enable_shared_from_this<Pastry<T>>

and equivalently in the other classes.

user17732522
  • 53,019
  • 2
  • 56
  • 105