2012-11-07 15 views
10

muszę coś zrobić, jak to często więcej niż:Jak połączyć korzystanie z std :: wiążą z std :: shared_ptr

AsyncOperation * pAsyncOperation = new AsyncOperation(); 
auto bindOperation = std::bind(&AsyncOperation::operator(), std::ref(*pAsyncOperation)); 
std::thread thread(bindOperation); 
thread.join(); 

z AsyncOperation jest każda klasa zwyczaj wykonawczych operator()(znany również jako funktora lub obiekt funkcji).

Czy można wskazać std::bind, aby użyć std::shared_ptr zamiast std::ref? Zapobiegłoby to wyciekom pamięci, bez konieczności przechowywania odniesienia na pAsyncOperation, i automatycznie usuwałbym AsyncOperation na końcu wątku, czyli na końcu tego asynchronicznego zadania.

EDYCJA: Nie zawsze mam dostęp do std :: thread, biblioteka wątków może być doładowania :: wątku lub nawet innych wątków zależnych od platformy. I w konsekwencji nie ma dostępu do std :: async.

Moim głównym problemem jest posiadanie pojęcia posiadania w std :: bind.

+0

Czy próbowałeś użyć 'std :: shared_ptr'? Wygląda na to, że kompiluje się bez problemów: http://liveworkspace.org/code/1e83d9698703711b7ed2ce0d44cf86f2 – PiotrNycz

+1

Musisz wiedzieć, że 'std :: bind' przechowuje powiązane argumenty według wartości (tj. Jako przekazane), dlatego jeśli przekazujesz posiadanie wskaźnik według wartości jako jeden z parametrów, wskaźnik ten zostaje "skopiowany" do wynikowego funktora, a więc posiadanie własności nawet po tym, jak pierwotny "shared_ptr" wykracza poza zakres. – haelix

Odpowiedz

10

to działa:

struct AsyncOperation { 
    void operator()() 
    { 
     std::cout << "AsyncOperation" << '\n'; 
    } 
}; 

int main() { 
    std::shared_ptr<AsyncOperation> pAsyncOperation = std::make_shared<AsyncOperation>(); 
    auto bindOperation = std::bind(&AsyncOperation::operator(), pAsyncOperation); 
    std::thread thread(bindOperation); 
    thread.join(); 
} 

Patrz: http://liveworkspace.org/code/4bc81bb6c31ba7b2bdeb79ea0e02bb89

+0

Czy potrzebujesz użyć 'make_shared', czy też' std :: shared_ptr pAsyncOperation (new AsyncOperation()); 'do? – akaltar

+1

@akaltar możesz używać obu "stylów" - ale make_shared jest lepszy - czytaj: https://stackoverflow.com/questions/31232146/why-is-it-better-to-use-stdmake-instead-of-- konstruktor – PiotrNycz

7

Potrzebujesz dynamicznego przydzielania numeru AsyncOperation? Jeśli nie, to byłoby to zrobić:

auto f = std::async([]{ AsyncOperation()(); }); 
f.wait(); 

inaczej:

std::unique_ptr<AsyncOperation> op(new AsyncOperation); 
auto f = std::async([&]{ (*op)(); }); 
f.wait(); 

Można oczywiście użyć std::thread, ale może ona dostarczyć więcej problemów (tzn obsługi wyjątków w innym wątku). std::bind ma również własne problemy i prawdopodobnie lepiej skończyć z lambda.

Jeśli naprawdę potrzebujesz, aby zdać prawo własności do innego wątku można również zrobić:

std::unique_ptr<AsyncOperation> op(new AsyncOperation); 
auto f = std::async([&](std::unique_ptr<AsyncOperation> op){ (*op)(); }, std::move(op)); 
f.wait(); 

jak lambdas nie obsługują typu ruch oddaje jeszcze.

Mam nadzieję, że to pomaga.

Powiązane problemy