L'instruction switch dans C/C est un puissant mécanisme de flux de contrôle qui permet un branchement efficace basé sur des valeurs entières . Cependant, il est souvent souhaitable d'activer des valeurs non entières, telles que des chaînes ou des énumérations. Cela présente un défi car les instructions switch n'acceptent que les arguments entiers.
Une approche traditionnelle pour gérer les arguments switch non entiers consiste à utiliser une séquence d'instructions if :
if( str == "foo" ) ... else if( str == "bar" ) ... else ...
Cependant, cette approche est inefficace car elle nécessite une complexité temporelle linéaire (O(n)) pour n cas. Une solution plus efficace consiste à représenter les valeurs non entières sous forme d'entiers, soit à l'aide de cartes, soit de ifs imbriqués. Cependant, ces approches peuvent être complexes et sujettes aux erreurs.
À l'aide de macros, il est possible d'implémenter une recherche binaire déroulée au moment de la compilation, permettant une analyse rapide et syntaxique. -approche conviviale :
#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)
Cette macro générera une fonction qui prend une chaîne en entrée et renvoie un booléen, implémentant une recherche binaire à travers le spécifié cas.
En C 11, les lambdas et les listes d'initialiseurs offrent une approche plus élégante et concise :
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; }
En C moderne, les techniques de métaprogrammation C 11 peuvent être utilisées pour créer un trie au moment de la compilation, une structure de données avancée qui peut gérer efficacement les branches de cas non triées :
#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; }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!