-1

I have a Request_manager class with nested classes in it:

class Request_manager {
    public:
        class Ticket {
        protected:
            explicit Ticket(System_time start_time);
            virtual void start() = 0;
        }
        struct ticket_element_{
            int app;
            std::shared_ptr <Ticket> ticket;
        };
    
        class Tickets_Queue{
        private:
            std::queue <ticket_element_> m_queue;
    
        public:
            void push(ticket_element_ ticket);
        };
    };

Request_manager::Ticket is a parent class from other classes such as Ticket, which have their own implementation of start():

class Ticket : public Request_manager::Ticket,
               public std::enable_shared_from_this<Ticket> {
    void start();
};

ticket_element_ may save the different children coming from Request_manager::Ticket. In the implementation of Request_manager::Tickets_Queue::push I do:

void Request_manager::Tickets_Queue::push(ticket_element_ ticket_container){
    run_async(ticket_container.app, async::Policy::FIFO,
        [ticket_container]() { ticket_container.ticket->start(); });
}

I get the error:

In file included from data_interfaces/Request_manager.cpp:1:0:
data_interfaces/Request_manager.h: In lambda function:
data_interfaces/Request_manager.h:31:22: error: ‘virtual void dataserver::Request_manager::Ticket::start()’ is protected
         virtual void start() = 0;
                      ^
data_interfaces/Request_manager.cpp:66:67: error: within this context
             [ticket_container]() { ticket_container.ticket->start(); });

Which I do not understand as I should be able to access the protected method once I have the object

Hector Esteban
  • 1,011
  • 1
  • 14
  • 29

1 Answers1

0

In ticket_container.ticket->start(); you are trying to access a protected method from a shared pointer, which has no access to it in the base class Request_manager::Ticket so it can't apply the vtable.

If you change the protected to public in Request_manager::Ticket it will work as it can access the method and apply the vtable thus calling the derived Ticket.

I've added/changed a little to be able to reproduce:

class Request_manager
{
public:
    class Ticket {
    protected:
        explicit Ticket() {}
        ~Ticket() {}
    public:
        virtual void start() = 0;
    };
    struct ticket_element_{
        int app;
        std::shared_ptr <Ticket> ticket;
    };
    
    class Tickets_Queue{
    private:
        std::queue <ticket_element_> m_queue;
    
    public:
        void push(ticket_element_ ticket);
    };

    Tickets_Queue _queue;
};

class Ticket : public Request_manager::Ticket,
                 public std::enable_shared_from_this<Ticket>
{
public:
    void start() {
        cout << "Starting ticket" << endl;
    }
};


void Request_manager::Tickets_Queue::push(ticket_element_ ticket_container){
    ticket_container.ticket->start();
}


int main() {
    Request_manager rm;

    rm._queue.push ({0, make_shared<Ticket>()});
    
    return 0;
}
manuel@desktop:~/projects$ g++ -Wall -Wextra -g main.cc -o main --std=gnu++2a -Wpedantic && time ./main
Starting ticket
Manuel
  • 2,526
  • 1
  • 13
  • 17