Sto creando una coda di lavoro. Il lavoro verrà creato nel thread A, quindi il lavoro verrà inviato al thread B e il thread B svolgerà il lavoro. Dopo che il lavoro è stato fatto, il lavoro verrà inviato al filo A.Troppe copie durante il binding di argomenti modello variad.
#include <functional>
#include <iostream>
#include <memory>
using namespace std;
template<typename T, typename... Args>
class Job
{
public:
Job(std::weak_ptr<T> &&wp, std::function<void(const Args&...)> &&cb)
: _cb(std::move(cb)),
_cbWithArgs(),
_owner(std::move(wp)) {}
public:
template<typename... RfTs>
void bind(RfTs&&... args)
{
// bind will copy args for three times.
_cbWithArgs = std::bind(_cb, std::forward<RfTs>(args)...);
}
void fire()
{
auto sp = _owner.lock();
if (sp)
{
_cbWithArgs();
}
}
private:
std::function<void(const Args& ...)> _cb;
std::function<void()> _cbWithArgs;
std::weak_ptr<T> _owner;
};
struct Args
{
Args() = default;
Args(const Args &args)
{
cout << "Copied" << endl;
}
};
struct Foo
{
void show(const Args &)
{
cout << "Foo" << endl;
}
};
int main()
{
using namespace std::placeholders;
shared_ptr<Foo> sf (new Foo());
Args args;
// Let's say here thread A created the job.
Job<Foo, Args> job(sf, std::bind(&Foo::show, sf.get(), _1));
// Here thread B has finished the job and bind the result to the
// job.
job.bind(args);
// Here, thread A will check the result.
job.fire();
}
I codici di cui sopra si compila e opere. Ma dà i seguenti risultati (g ++ 4.8.4 & clang hanno gli stessi risultati):
Copied
Copied
Copied
Foo
ci sono tre copie! Non accettabile, non so dove ho sbagliato. Perché tre copie? Ho cercato su Google e trovato un metodo da qui: https://stackoverflow.com/a/16868401, copia solo i parametri per una volta. Ma deve inizializzare la funzione bind nel costruttore.
Grazie, Piotr Skotnicki. Sfortunatamente, non ho un compilatore C++ 14. Quindi, facciamo i Args mobile:
struct Args
{
Args() = default;
Args(const Args &args)
{
cout << "Copied" << endl;
}
Args(Args &&) = default;
Args& operator=(Args &&) = default;
};
Ora, copys solo una volta :)
Infine, ho adottato i codici da questa discussione https://stackoverflow.com/a/16868151/5459549. Il modello gen_seq è vero ART, devo dire.
Purtroppo non viene compilato in VC14, std :: tuple deve inizializzare – MORTAL
@MORTAL * "Purtroppo non si compila in VC14, std :: la tupla deve essere inizializzata "*, puoi elaborare? –
grazie per la risposta informativa, ho eseguito il codice in VC14 non compilato, restituisce errore come 'tuple (67): errore C2476: il costruttore 'constexpr' non inizializza tutti i membri'. non so se questo potrebbe essere un altro bug con VC14 – MORTAL