Ich habe eine Signal
Klasse in meiner Anwendung, die Klassen mit einer Option zur Verfügung stellt, Ereignisse (wie in. NET).C++ 11 Std :: einen Zeiger weiterleiten
Die Klasse funktioniert und alles ist gut.
Gestern sah ich this SO question (and its answer) und wurde vertraut gemacht mit std::forward
.
ich es in meinem Code zu verwenden, um zu versuchen entschieden, damit ich jeden std::function<void(Args...)>
zu std::function<void(Args&&...)>
und in der Erhöhung Funktion (die operator()
) geändert habe ich die gleiche Logik, die ich in dem obigen Link sah so jetzt die Funktion nimmt Args&&...args
und den Rückruf std::forward<Args>(args)...
verwendet
Hier ist eine vereinfachte Version meiner Signalklasse (mit einigen Änderungen es ein gutes Beispiel zu machen):
template<typename... Args> class Signal
{
public:
int operator+=(const std::function<void(Args&&...)>& func) {
int token = getNewToken();
m_subscribers.emplace(token, func);
return token;
}
void operator()(Args&&... args) {
for (auto it : m_subscribers) {
it.second(std::forward<Args>(args)...);
}
}
private:
std::map<int, std::function<void(Args&&...)>> m_subscribers;
};
int main() {
int* six = new int(6);
int seven = 7;
Signal<int*> e1;
e1 += [](int* x) { std::cout << *x; };
Signal<int> e2;
e2 += [](int x) { std::cout << x; };
e1(&seven);
e2(6);
e1(six); //Error C2664 'void Signal<int *>::operator()(int *&&)':
// cannot convert argument 1 from 'int *' to 'int *&&'
e1(std::move(six)); //This is a workaround
return 0;
}
Die Frage, die ich zu sehen bin mit Klassen (oder main
in diesem Beispiel) ist, dass Versuchen Sie, Ereignisse mit pointe auszulösen rs und ich bin mir nicht sicher, wie ich das lösen soll.
Mein Hauptziel ist es, die Signal-Klasse eine allgemeine API zu haben, und wenn die Entwickler Signal<int*>
verwenden, möchte ich nicht, dass er mit std::move
erhöht.
Was mache ich hier falsch?
@WernerErasmus Ja. Wenn Sie mehrere Abonnenten haben, können Sie dieselben Argumente nicht mehrfach weiterleiten. – Barry
Danke Barry, außer dem 'using F' Teil, das ist der Code den ich bereits benutze. Ihre Antwort ist also gewissermaßen "Sie können und sollten in diesem Fall nicht std :: forward verwenden"? – ZivS
Ich bin mehr daran interessiert, wie und ob ich std :: forward mit allen Typen verwenden kann. Ich habe das Gefühl, dass ich mehr darüber lesen sollte, da der erste Absatz Ihrer Antwort ein wenig nuklear für mich war ... – ZivS