Fehler 1: Entschuldigung, nicht implementiert: „Listener …“ kann nicht in eine Argumentliste mit fester Länge erweitert werden.
Fehler 2: i kann nicht in einem konstanten Ausdruck erscheinen.
Also, wie iteriere ich korrekt über die Elemente eines Tupels?
Darf ich fragen, wie Sie in C++0x kompilieren? Soweit ich weiß, ist es weder veröffentlicht noch fertig.
– Burkhard
29. Juli 2009 um 6:09 Uhr
g++ enthält seit Version 4.3 experimentelle Unterstützung einiger C++0X-Features, einschließlich variadischer Templates. Andere Compiler machen dasselbe (mit unterschiedlichen Feature-Sets, wenn Sie sie in der Produktion verwenden möchten, sind Sie zurück in den 90er Jahren mit einer breiten Palette an Unterstützung für bahnbrechende Dinge)
– Ein Programmierer
29. Juli 2009 um 7:10 Uhr
Ich verwende g++ Version 4.4 mit std=c++0x
– 1521237
30. Juli 2009 um 10:33 Uhr
Diese Frage erfordert ein C++11-Update.
– Allmächtig
3. Februar 2013 um 4:04 Uhr
@Omnifarious jetzt braucht es ein C++14-Update
– pfeffer_chico
19. April 2014 um 15:38 Uhr
emsr
Ich habe eine Antwort, die auf dem Iterieren über ein Tupel basiert:
Die übliche Idee ist die Rekursion zur Kompilierzeit. Tatsächlich wird diese Idee verwendet, um ein printf zu erstellen, das typsicher ist, wie in den ursprünglichen Tupelpapieren angegeben.
Dies lässt sich leicht zu a verallgemeinern for_each für Tupel:
Dies erfordert dann allerdings etwas Aufwand FuncT etwas mit den entsprechenden Überladungen für jeden Typ darstellen, den das Tupel enthalten könnte. Dies funktioniert am besten, wenn Sie wissen, dass alle Tupelelemente eine gemeinsame Basisklasse oder etwas Ähnliches haben.
Danke für das schöne einfache Beispiel. Für C++-Anfänger, die nach Hintergrundinformationen zur Funktionsweise suchen, siehe SFINAE und enable_if Dokumentation.
– Faheem Mitha
12. Februar 2012 um 5:28 Uhr
Dies könnte leicht zu einem Generikum verallgemeinert werden for_each. Tatsächlich habe ich es selbst gemacht. 🙂 Ich denke, diese Antwort wäre nützlicher, wenn sie bereits verallgemeinert wäre.
– Allmächtig
3. Februar 2013 um 11:27 Uhr
Dort habe ich die Verallgemeinerung hinzugefügt, weil ich tatsächlich eine brauchte und ich denke, dass es für andere nützlich wäre, sie zu sehen.
– Allmächtig
4. Februar 2013 um 7:06 Uhr
Hinweis: Möglicherweise benötigen Sie auch Versionen mit const std::tuple<Tp...>&.. Wenn Sie nicht beabsichtigen, Tupel während der Iteration zu ändern, sind diese const Versionen genügen.
– tödliche Gitarre
6. Juni 2013 um 19:17 Uhr
Nicht wie geschrieben.. Sie könnten eine Version mit umgedrehter Indizierung erstellen – beginnen Sie bei I = sizeof … (Tp) und zählen Sie herunter. Geben Sie dann explizit eine maximale Anzahl von Argumenten an. Sie könnten auch eine Version erstellen, die bei einem Tag-Typ kaputt geht, sagen wir break_t. Dann würden Sie ein Objekt dieses Tag-Typs in Ihr Tupel einfügen, wenn Sie das Drucken stoppen wollten. Oder Sie könnten einen Stopptyp als Vorlagenparameter bereitstellen. Offensichtlich konnten Sie nicht zur Laufzeit brechen.
Diese Lösung löst das Problem der Bewertungsreihenfolge in der Antwort von M. Alaggan.
Können Sie erklären, was hier passiert: ((std::cout << args << '\n'), ...); ? Das Lambda wird einmal aufgerufen, wobei die Tupelelemente als entpackt werden argsaber was hat es mit den doppelten Klammern auf sich?
– helmesjo
19. Januar 2019 um 22:17 Uhr
@helmesjo Es wird zu einem Kommaausdruck erweitert ((std::cout << arg1 << '\n'), (std::cout << arg2 << '\n'), (std::cout << arg3 << '\n')) Hier.
– xskxzr
20. Januar 2019 um 3:37 Uhr
Beachten Sie, dass Sie für den Fall, dass Sie Dinge tun möchten, die in einem Komma-Ausdruck nicht zulässig sind (wie das Deklarieren von Variablen und Blöcken), all dies in eine Methode packen und sie einfach innerhalb des gefalteten Komma-Ausdrucks aufrufen können.
– Miral
27. Februar 2020 um 7:00 Uhr
Daniel Steck
C++ wird eingeführt Erweiterungserklärungen für diesen Zweck. Sie waren ursprünglich auf dem Weg zu C++20, verpassten die Kürzung jedoch knapp, da die Zeit für die Überprüfung der Sprachformulierung fehlte (siehe Hier und Hier).
Die derzeit vereinbarte Syntax (siehe die obigen Links) lautet:
{
auto tup = std::make_tuple(0, 'a', 3.14);
template for (auto elem : tup)
std::cout << elem << std::endl;
}
Dies funktioniert bereits in Clang++ 3.9 mit std::experimental::apply.
Führt dies nicht zur Iteration – dh Aufrufen von do_something() – in unbestimmter Reihenfolge auftreten, da das Parameterpaket innerhalb eines Funktionsaufrufs expandiert wird (), wobei Argumente eine unbestimmte Reihenfolge haben? Das könnte sehr bedeutsam sein; Ich würde mir vorstellen, dass die meisten Leute erwarten würden, dass die Reihenfolge garantiert in der gleichen Reihenfolge wie die Mitglieder erfolgt, dh wie die Indizes std::get<>(). AFAIK, um in solchen Fällen eine garantierte Bestellung zu erhalten, muss die Erweiterung innerhalb von erfolgen {braces}. Liege ich falsch? Diese Antwort betont eine solche Reihenfolge: stackoverflow.com/a/16387374/2757035
– Unterstrich_d
9. Oktober 2016 um 14:37 Uhr
Verwenden Sie Boost.Hana und generische Lambdas:
#include <tuple>
#include <iostream>
#include <boost/hana.hpp>
#include <boost/hana/ext/std/tuple.hpp>
struct Foo1 {
int foo() const { return 42; }
};
struct Foo2 {
int bar = 0;
int foo() { bar = 24; return bar; }
};
int main() {
using namespace std;
using boost::hana::for_each;
Foo1 foo1;
Foo2 foo2;
for_each(tie(foo1, foo2), [](auto &foo) {
cout << foo.foo() << endl;
});
cout << "foo2.bar after mutation: " << foo2.bar << endl;
}
Führt dies nicht zur Iteration – dh Aufrufen von do_something() – in unbestimmter Reihenfolge auftreten, da das Parameterpaket innerhalb eines Funktionsaufrufs expandiert wird (), wobei Argumente eine unbestimmte Reihenfolge haben? Das könnte sehr wichtig sein; Ich würde mir vorstellen, dass die meisten Leute erwarten würden, dass die Reihenfolge garantiert in der gleichen Reihenfolge wie die Mitglieder erfolgt, dh wie die Indizes std::get<>(). AFAIK, um in solchen Fällen eine garantierte Bestellung zu erhalten, muss die Erweiterung innerhalb von erfolgen {braces}. Liege ich falsch? Diese Antwort betont eine solche Reihenfolge: stackoverflow.com/a/16387374/2757035
– Unterstrich_d
9. Oktober 2016 um 14:37 Uhr
Eine einfachere, intuitivere und Compiler-freundlichere Methode, dies in C++17 zu tun, ist die Verwendung von if constexpr:
// prints every element of a tuple
template<size_t I = 0, typename... Tp>
void print(std::tuple<Tp...>& t) {
std::cout << std::get<I>
// do things
if constexpr(I+1 != sizeof...(Tp))
print<I+1>
}
Dies ist eine Rekursion zur Kompilierzeit, ähnlich der von @emsr. Aber das verwendet SFINAE nicht, also ist es (glaube ich) Compiler-freundlicher.
9989700cookie-checkWie können Sie über die Elemente eines std::tuple iterieren?yes
This website is using cookies to improve the user-friendliness. You agree by using the website further.
Darf ich fragen, wie Sie in C++0x kompilieren? Soweit ich weiß, ist es weder veröffentlicht noch fertig.
– Burkhard
29. Juli 2009 um 6:09 Uhr
g++ enthält seit Version 4.3 experimentelle Unterstützung einiger C++0X-Features, einschließlich variadischer Templates. Andere Compiler machen dasselbe (mit unterschiedlichen Feature-Sets, wenn Sie sie in der Produktion verwenden möchten, sind Sie zurück in den 90er Jahren mit einer breiten Palette an Unterstützung für bahnbrechende Dinge)
– Ein Programmierer
29. Juli 2009 um 7:10 Uhr
Ich verwende g++ Version 4.4 mit std=c++0x
– 1521237
30. Juli 2009 um 10:33 Uhr
Diese Frage erfordert ein C++11-Update.
– Allmächtig
3. Februar 2013 um 4:04 Uhr
@Omnifarious jetzt braucht es ein C++14-Update
– pfeffer_chico
19. April 2014 um 15:38 Uhr