0

I'm using libtins to capture packets and moodycamel Concurrent Queue to queue captured packets.

This std::make_unique<Tins::PDU>(pdu.clone()) fails to compile,

error: invalid new-expression of abstract class type Tins::PDU { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }

I was using the answer given by the user of my co-related question.

The PDU type is an abstract class. How to fix this as It seems make_unique need to know the sub class type?

Like, std::unique_ptr<A> bse = std::make_unique<B>(bObject); but I can't know the B aka sub class type in advance.

moodycamel::ConcurrentQueue<std::unique_ptr<Tins::PDU>> packetQueue;

void worker()
{
    while(true) {
        std::unique_ptr<Tins::PDU> pdu;

        if(packetQueue.try_dequeue(pdu) == false) {
            continue;
        }

        // Do Work on *pdu
    }
}

bool callback(PDU &pdu)
{
  packetQueue.enqueue(std::make_unique<Tins::PDU>(pdu.clone()));

  return true;
}
jeffbRTC
  • 1,941
  • 10
  • 29
  • `make_unique` will instantiate the object. As mentioned in your [last question](https://stackoverflow.com/questions/68485187), you can not create an object of type `Tins::PDU`, by design. – Drew Dormann Jul 22 '21 at 19:29
  • @DrewDormann But it doesn't compile!!!!! – jeffbRTC Jul 22 '21 at 19:31
  • I suppose that `pdu.clone()` returns a `std::unique_ptr` per the classic Clone pattern, so why are you using `std::make_unique` on top of it? – Quentin Jul 22 '21 at 19:35
  • @Quentin Because the author of answer said so. – jeffbRTC Jul 22 '21 at 19:36
  • Well, they've probably made a typo. The Clone pattern *is* a solution to the problem of deep-copying an object of unknown dynamic type, but it's supposed to return the new, type-erased object. – Quentin Jul 22 '21 at 19:39
  • @Quentin Well, the clone function signature seems suggest that it returns only a pointer not a smart unique pointer – jeffbRTC Jul 22 '21 at 19:41
  • Right, and alas. The syntax to take ownership of a raw owning pointer is through `std::unique_ptr(pdu.clone())`. `packetQueue.emplace(pdu.clone())` might compile as well and call the same constructor, but I'm not sure whether `emplace` calls `explicit` constructors. – Quentin Jul 22 '21 at 19:43
  • @Quentin `packetQueue.emplace(pdu.clone())` doesn't work. Also, there is no `emplace` rather `enqueue`. – jeffbRTC Jul 22 '21 at 19:49
  • My bad, I thought that was an `std::queue`. Still, that's how to construct a `std::unique_ptr` from a raw owning pointer. If that still doesn't work on your side, you should update your question with the exact error you're now receiving. – Quentin Jul 22 '21 at 19:52
  • @Quentin `std::unique_ptr(pdu.clone())` works. – jeffbRTC Jul 22 '21 at 19:56
  • @DrewDormann, you gave me a big clue here. So "make" in this context literally means "create", not "cause to become" as I had believed. Thanks! – Edd Inglis Jan 01 '22 at 22:08

0 Answers0