ThreadPool icon indicating copy to clipboard operation
ThreadPool copied to clipboard

Problem with passing std::unique_ptr

Open lordnn opened this issue 4 years ago • 3 comments

#include "ThreadPool.h"
#include <stdio.h>

class Foo {
public:
    Foo();
    void Process(std::unique_ptr<uint16_t[]> im);
private:
    void ProcessImpl(std::unique_ptr<uint16_t[]> im);
    ThreadPool t;
};

Foo::Foo() : t(4) {
}

void Foo::Process(std::unique_ptr<uint16_t[]> im) {
#if 0
    ProcessImpl(std::move(im));
#else
    t.enqueue(&Foo::ProcessImpl, this, std::move(im));
#endif
}

void Foo::ProcessImpl(std::unique_ptr<uint16_t[]> im) {
    printf("%p\n", im.get());
}

int main()
{
    Foo f;
    auto p = std::make_unique<uint16_t[]>(100);
    printf("%p\n", p.get());

    f.Process(std::move(p));
}

This doesn't compile.

lordnn avatar Nov 07 '21 01:11 lordnn

this worked

#include "ThreadPool.h"
#include <cstdint>
#include <stdio.h>

class Foo {
public:
    Foo();
    void Process(std::unique_ptr<uint16_t[]> im);
private:
    void ProcessImpl(std::shared_ptr<uint16_t[]> im);
    ThreadPool t;
};

Foo::Foo() : t(4) {
}

void Foo::Process(std::unique_ptr<uint16_t[]> im) {
#if 0
    ProcessImpl(std::move(im));
#else
    std::shared_ptr<uint16_t[]> p = std::move(im);
    t.enqueue(&Foo::ProcessImpl, this, std::move(p));
#endif
}

void Foo::ProcessImpl(std::shared_ptr<uint16_t[]> im) {
    printf("%p %ld\n", im.get(), im.use_count());
}

int main()
{
    Foo f;
    auto p = std::make_unique<uint16_t[]>(100);
    printf("%p\n", p.get());

    f.Process(std::move(p));
}

out:

0x10fe3f0
0x10fe3f0 2

https://stackoverflow.com/questions/20268482/binding-functions-with-unique-ptr-arguments-to-stdfunctionvoid

lasorda avatar Mar 16 '22 08:03 lasorda

So, problem with passing std::unique_ptr still here. :(

lordnn avatar Apr 11 '22 17:04 lordnn

@lordnn change fn Process like this will use

void Foo::Process(std::unique_ptr<uint16_t[]> im) {
#if 0
    ProcessImpl(std::move(im));
#else
    auto f = [this, p = std::move(im)]() mutable {
        this->ProcessImpl(std::move(p));
    };
    t.enqueue(std::move(f));
#endif
}

explaining are here https://stackoverflow.com/questions/8640393/move-capture-in-lambda/20669290#20669290

love1angel avatar Feb 02 '23 09:02 love1angel