zur Reduzierung von Boilerplate Code um mich an eine "C-Artige"
Schnittstelle zu adaptieren die schon existiert implementiere
für jede Klasse die ich anbinden möchte ein Template was das
durchreichen von Parametern stark vereinfacht und dabei noch
Kontext-Keys (für ein Storage-System) mitliefert - jetzt wollte ich den
immer (bis auf die Keys) gleiche Code aus den InnerEvalAndStore mit
einem allgemeinen OuterEvalAndStore Template ersetzen scheitere aber
aber daran die Varianten Anzahl an Keys und die Variante Anzahl an
Methode-Paramater miteinander zu kombinieren
hat jemand eine Idee wie man so was machen könnte?
hier mein etwas längerer Beispiel-Code - Sorry :{
gcc.godbolt.org: https://gcc.godbolt.org/z/9ceG1z
1
#include<string>
2
3
// "C-Artige"-Schnittstelle an die ich mich adaptieren will
Direkt ins Schwarze beim 1. Versuch - danke Niklas
gcc.godbolt.org: https://gcc.godbolt.org/z/f37jr8
und so lange meine Keys keine Strings sind ist das inlining auch super
1
#include<tuple>
2
#include<string>
3
4
// "C-Artige"-Schnittstelle an die ich mich adaptieren will
@Niklas
bald musst du dich entscheiden ob es ein Obstkorb mit Früchten der
Südsee oder so ein Metzger-Körbchen mit grober Leberwurst und Speck
werden soll :)
cppbert3 schrieb:> OuterEvalAndStore<StoreFunc>(target_, std::tuple{> std::forward<Values>(values_)... },> std::tuple{ m_key1, m_key2 });
Versuch mal Referenzen in das Tupel zu speichern, dann vermeidet man das
Kopieren der Keys, dürfte inlined auch kompakter werden:
cppbert3 schrieb:> bald musst du dich entscheiden ob es ein Obstkorb mit Früchten der> Südsee oder so ein Metzger-Körbchen mit grober Leberwurst und Speck> werden soll :)
Haha, na andere sind hier ja auch sehr produktiv ;-)
Niklas G. schrieb:> cppbert3 schrieb:>> OuterEvalAndStore<StoreFunc>(target_, std::tuple{>> std::forward<Values>(values_)... },>> std::tuple{ m_key1, m_key2 });>> Versuch mal Referenzen in das Tupel zu speichern, dann vermeidet man das> Kopieren der Keys, dürfte inlined auch kompakter werden:> OuterEvalAndStore<StoreFunc>(target_, std::tuple{> std::forward<Values>(values_)... }, std::tie (m_key1, m_key2));
Ergibt Micro-Unterschiede - aber ich schreibe es mir mal dazu
> cppbert3 schrieb:>> bald musst du dich entscheiden ob es ein Obstkorb mit Früchten der>> Südsee oder so ein Metzger-Körbchen mit grober Leberwurst und Speck>> werden soll :)>> Haha, na andere sind hier ja auch sehr produktiv ;-)
auf jeden Fall, jetzt gerade bist aber nur du hier - und hast mir auch
schon echt oft schnell und gut geholfen, oder stalkst du meine Posts und
ich muss mir sorgen machen? :)
cppbert3 schrieb:> Ergibt Micro-Unterschiede - aber ich schreibe es mir mal dazu
Gut, könnte sein dass der Compiler sonst nicht sieht dass das Kopieren
des Strings unnötig ist und ihn eben unnötig kopiert.
cppbert3 schrieb:> und hast mir auch> schon echt oft schnell und gut geholfen, oder stalkst du meine Posts und> ich muss mir sorgen machen? :)
Ne, ich klicke nur auf alles wo "C++" steht ;-) Die C++ Community auf
Stack-Overflow ist auch sehr gut, und für schnelle Hilfe ist der
Cpplang-Slack auch gut: https://cppalliance.org/slack/
PS: Mir fällt gerade auf dass ich einen Copy-Paste-Fehler gemacht habe,
in der Parameter-Liste sollte "target_" eine Referenz sein:
Niklas G. schrieb:> cppbert3 schrieb:>> Ergibt Micro-Unterschiede - aber ich schreibe es mir mal dazu>> Gut, könnte sein dass der Compiler sonst nicht sieht dass das Kopieren> des Strings unnötig ist und ihn eben unnötig kopiert.
dann mache ich es jetzt rein
Niklas G. schrieb:> PS: Mir fällt gerade auf dass ich einen Copy-Paste-Fehler gemacht habe,> in der Parameter-Liste sollte "target_" eine Referenz sein:
Mensch, Niklas!!!
in meiner echten Implementierung habe ich jetzt mehrere (3)
Funktion-Templates welche die ...Keys, ...Values und noch ein paar
andere Objekte brauchen
die ...Keys und anderen Objekte brauchen alle
könnte man die irgendwie in eine Template-Klasse stecken welche ich dann
lokal privat Instanziere damit ich die Keys immer da habe
also in der Art
Sieht doch schon gut aus. Durch den strategischen Einsatz von std::move
im Konstruktur, und Overloads für verschiedene Referenz-Typen des
"keys_"-Arguments kann man Kopien vermeiden, ohne die Typsicherheit zu
verlieren:
Niklas G. schrieb:> Sieht doch schon gut aus. Durch den strategischen Einsatz von> std::move> im Konstruktur, und Overloads für verschiedene Referenz-Typen des> "keys_"-Arguments kann man Kopien vermeiden, ohne die Typsicherheit zu> verlieren:> class Helper {> Helper (obj1, obj2, std::tuple<Keys...>&& keys_) : m_keys (std::move> (keys_)) {}> Helper (obj1, obj2, const std::tuple<Keys...>& keys_) : m_keys (keys_)> {}> Oder nur den 1. gezeigten Overload behalten, falls man sowieso nie> "const&" braucht.
meine Keys sind unveränderlich also eigentlich immer (const) members -
die duerfen sich nie aendern
So wird aber immer kopiert... Wär's nicht sinnvoller, aus "m_keys" eine
Referenz zu machen? Sind die Keys ein Member der äußeren Klasse (oben:
"Test")? Dann hast du eine gewisse Duplikation.
Niklas G. schrieb:> So wird aber immer kopiert... Wär's nicht sinnvoller, aus "m_keys"> eine> Referenz zu machen? Sind die Keys ein Member der äußeren Klasse (oben:> "Test")? Dann hast du eine gewisse Duplikation.
ja das sind die Keys der äußeren Klasse von der es eben X Varianten gibt
die Keys sind eigentlich sogar const (mache ich jetzt) weil die niemals
veraendert werden duerfen
wie wäre es denn ideal wenn die m_key?s immer const wären und problemlos
per const& uebergeben werden können
bisher erzeuge ich so mein HelperObject
private: // internal
ModifierHelper<Store, decltype( m_key1 ), decltype( m_key2 )>
m_helper;
und im ctor dann so
, m_helper( m_store, { m_key1, m_key2 } )
Das heißt aber dass ModifierHelper nur Referenzen in das enthaltende
Objekt enthält. Daher ist es eher sinnlos permanent eine Instanz davon
zu haben. Wäre es nicht sinnvoller eine inline-Funktion zu definieren,
welche ein temporäres ModifierHelper-Objekt erzeugt und zurückgibt, mit
dem man dann jeweils arbeitet? Durch das inlining wird das Erstellen des
Objekts wegoptimiert.
Niklas G. schrieb:> Das heißt aber dass ModifierHelper nur Referenzen in das> enthaltende> Objekt enthält. Daher ist es eher sinnlos permanent eine Instanz davon> zu haben. Wäre es nicht sinnvoller eine inline-Funktion zu definieren,> welche ein temporäres ModifierHelper-Objekt erzeugt und zurückgibt, mit> dem man dann jeweils arbeitet? Durch das inlining wird das Erstellen des> Objekts wegoptimiert.
das hört sich auch gut an
d.h. ich ersetze meinen m_helper+ctor init
durch so eine Member-Funktion?