Das ist es, worauf mein Code hinausläuft, mit einer emplace-Funktion, die sich nicht kompilieren lässt, Ihnen aber hoffentlich klar macht, was ich erreichen möchte:
Code: Select all
template
class MyContainer
{
public:
template
void emplace(ArgsA&&... argsA, ArgsB&&... argsB)
{
// do custom logic
a_container.emplace_back(std::forward(argsA)...);
b_container.emplace_back(std::forward(argsB)...);
}
private:
std::vector a_container;
std::vector b_container;
};
Mit std::tuple kann das Problem also in ein paar verschiedene Schritte zerlegt werden. In jedem Schritt muss ich sicherstellen, dass die Art (R-Wert vs. L-Wert) der Argumente erhalten bleibt:
- Argumente an emplace in einem Tupel übergeben
- das Tupel aus meiner Emplace-Funktion lesen
- das Tupel entpacken
- die entpackten Tupelelemente an emplace_back(..) übergeben
Punkt 2. bringt ein wenig Unannehmlichkeiten mit sich. Das heißt, emplace so umzuschreiben, dass es std::tuple:
akzeptiert
Code: Select all
template
void emplace(std::tuple tupleA, std::tuple tupleB)
Außerdem denke ich, dass die Art und Weise, wie wir std::tuple weitergeben, zu einem seltsamen Verhalten führen kann. Oben habe ich eine „Lazy-Version“ geschrieben, die std::tuple per Kopie übernimmt, aber meistens, wenn ich einen Container schreibe, bevorzuge ich, wie auch der Standard, die Verwendung sowohl einer const std::tuple&- als auch einer std::tuple&&-Version für maximale Flexibilität. In diesem Fall wird die Version „const std::tuple&“ dazu führen, dass „std::get“ aufgrund von Referenz-Reduzierungsregeln nur die L-Werte-Version unserer Argumente extrahiert, was den Punkt zunichte macht. Deshalb denke ich darüber nach, nur std::tuple&& zu schreiben und (vielleicht) die Kopieversion beizubehalten.
Punkte 3. und 4. sind die schwierigsten. Ich schätze, ich muss sie gemeinsam lösen, und ich bin ziemlich überrascht, dass der Standard, soweit ich weiß, std::forward_as_tuple anbietet, aber nicht die umgekehrte Operation. Hier gibt es ein subtiles Problem, das die einfache Lösung der Weiterleitung mit Code wie diesem verhindert:
Code: Select all
template
void emplace(std::tuple tupleA, std::tuple tupleB)
{
// do custom logic
a_container.emplace_back(std::forward(std::get(tupleA))...);
...
Ich suche insbesondere nach einfacheren Lösungen für die Punkte 3. und 4.
Mobile version