327 votes

Pourquoi l’instruction switch ne peut s’appliquer sur des cordes ?

int main()
{
    switch(std::string("raj")) //Compilation error - switch expression of type illegal 
    {
    case"sda":
    }

}

257voto

JaredPar Points 333733

La raison a à voir avec le type de système. C/C++ n'est pas vraiment favorable à cordes comme un type. Il soutient l'idée d'une constante tableau de char, mais il n'a pas vraiment de comprendre pleinement la notion de chaîne de caractères.

Afin de générer le code d'une instruction switch le compilateur doit comprendre ce que cela signifie pour les deux valeurs sont égales. Pour les objets comme les entiers et les énumérations, c'est une simple comparaison de bits. Mais comment le compilateur comparer 2 valeurs de chaîne? Sensible à la casse, insensible, de culture, de connaissance, etc ... Sans une pleine prise de conscience d'une chaîne de cela ne peut pas être répondu avec précision à.

En outre, C/C++ instructions de commutation sont généralement générés en direction des tables. Il n'est pas aussi facile de générer une table de branchement pour une chaîne de style de l'interrupteur.

75voto

D.Shawley Points 30324

Comme mentionné précédemment, les compilateurs comme pour construire les tables de recherche qui permettent d'optimiser switch des déclarations à proximité de O(1) le calendrier chaque fois que possible. Combinez cela avec le fait que le Langage C++ n'est pas un type de chaîne - std::string fait partie de la Bibliothèque Standard qui ne fait pas partie de la Langue en soi.

Je vais proposer une solution de rechange que vous pourriez envisager, je l'ai utilisé dans le passé pour un bon effet. Au lieu de passer sur la chaîne elle-même, de passer le résultat d'une fonction de hachage qui utilise la chaîne en entrée. Votre code sera presque aussi clair que le passage sur la chaîne si vous utilisez un ensemble prédéterminé de chaînes de caractères:

enum string_code {
    eFred,
    eBarney,
    eWilma,
    eBetty,
    ...
};

string_code hashit (std::string const& inString) {
    if (inString == "Fred") return eFred;
    if (inString == "Barney") return eBarney;
    ...
}

void foo() {
    switch (hashit(stringValue)) {
    case eFred:
        ...
    case eBarney:
        ...
    }
}

Il ya un tas d'optimisations évidentes qu'assez bien suivi ce que le compilateur C ne avec une instruction switch... c'est drôle comment ça se passe.

35voto

MarmouCorp Points 647

Vous pouvez uniquement utiliser le commutateur sur primitifs tels qu’int, char et enum. La solution la plus simple de le faire comme vous voulez, consiste à utiliser un enum.

15voto

tomjen Points 2460

Le problème est que pour des raisons d'optimisation de l'instruction switch en C++ ne fonctionne pas sur quoi que ce soit mais les types primitifs, et vous ne pouvez les comparer avec la compilation des constantes de temps.

Sans doute la raison pour laquelle la restriction est que le compilateur est capable d'appliquer une certaine forme de l'optimisation de la compilation le code en bas à une instruction cmp et un goto où l'adresse est calculée sur la base de la valeur de l'argument au moment de l'exécution. Depuis la ramification et et les boucles ne jouent pas bien avec les Processeurs modernes, ce peut être un élément important de l'optimisation.

Pour contourner cela, je crains que vous devrez recourir à la si les déclarations.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X