progschj / ThreadPool

A simple C++11 Thread Pool implementation
zlib License
7.63k stars 2.21k forks source link

Problem with passing std::unique_ptr #93

Open lordnn opened 2 years ago

lordnn commented 2 years ago
#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.

lasorda commented 2 years ago

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

lordnn commented 2 years ago

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

love1angel commented 1 year ago

@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