Die switch-Anweisung in C/C ist ein leistungsstarker Kontrollflussmechanismus, der eine effiziente Verzweigung basierend auf ganzzahligen Werten ermöglicht . Allerdings ist es oft wünschenswert, nicht-ganzzahlige Werte wie Strings oder Enums einzuschalten. Dies stellt eine Herausforderung dar, da Switch-Anweisungen nur ganzzahlige Argumente akzeptieren.
Ein traditioneller Ansatz zur Handhabung nicht ganzzahliger Switch-Argumente besteht darin, eine Folge von if-Anweisungen zu verwenden:
if( str == "foo" ) ... else if( str == "bar" ) ... else ...
Dieser Ansatz ist jedoch ineffizient, da er für n Fälle eine lineare Zeitkomplexität (O(n)) erfordert. Eine effizientere Lösung besteht darin, die nicht ganzzahligen Werte als ganze Zahlen darzustellen, entweder mithilfe von Karten oder verschachtelten ifs. Diese Ansätze können jedoch komplex und fehleranfällig sein.
Mithilfe von Makros ist es möglich, eine abgerollte binäre Suche zur Kompilierungszeit zu implementieren, was eine schnelle und syntaktische Optimierung ermöglicht -freundlicher Ansatz:
#define NEWMATCH #define MATCH("asd") some c++ code #define MATCH("bqr") ... the buffer for the match is in _buf #define MATCH("zzz") ... user.YOURSTUFF #define ENDMATCH(xy_match)
Dieses Makro generiert eine Funktion, die eine Zeichenfolge als Eingabe verwendet und einen booleschen Wert zurückgibt, wodurch eine binäre Suche durch die angegebenen Daten implementiert wird Fälle.
In C 11 bieten Lambdas und Initialisierungslisten einen eleganteren und prägnanteren Ansatz:
template<typename KeyType, typename FunPtrType> void switchStatement(const KeyType& value, std::initializer_list<std::pair<const KeyType, FunPtrType>> sws) { std::lower_bound(sws.begin(), sws.end(), value, [&](const auto& a, const auto& b) { return a.first < b.first; }); if (r != sws.end() && !cmp(val, *r)) { r->second(); } // else: not found }
int main() { switchStatement<const char*, void(*())>("ger", { { "asdf", []{ printf("0\n"); } }, { "bde", []{ printf("1\n"); } }, { "ger", []{ printf("2\n"); } }, }); return 0; }
In modernem C können C 11-Metaprogrammierungstechniken verwendet werden, um einen Trie zur Kompilierungszeit zu erstellen Erweiterte Datenstruktur, die unsortierte Fallzweige effizient verarbeiten kann:
#include <smile/cttrie/cttrie.h> using namespace smile::cttrie; // Define cases as string literals trie<true, void()> s = {"foo", "bar"}; int main() { // Switch on a string s.switch_on("foo", []() { std::cout << "foo" << std::endl; }); return 0; }
Das obige ist der detaillierte Inhalt vonWie kann ich eine Switch-Anweisung mit nicht ganzzahligen Argumenten in C/C effizient implementieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!