Frage

Ich habe recherchiert mein Problem alle über StackOverflow und multi-google-links, und ich bin immer noch verwirrt.Ich dachte, das beste für mich ist, Fragen Sie...

Im creating a simple command-line calculator.Hier ist mein code so weit:

const std::string Calculator::SIN("sin");  
const std::string Calculator::COS("cos");  
const std::string Calculator::TAN("tan");  
const std::string Calculator::LOG( "log" );  
const std::string Calculator::LOG10( "log10" );

void Calculator::set_command( std::string cmd ) {

    for(unsigned i = 0; i < cmd.length(); i++)
    {
    cmd[i] = tolower(cmd[i]);
    }

    command = cmd;
}

bool Calculator::is_legal_command() const {

    switch(command)
    {
    case TAN:
    case SIN:
    case COS:
    case LOG:
    case LOG10:
        return true;
        break;
    default:
        return false;
        break;
    }

}

der Fehler, den ich bekomme, ist:

Calculator.cpp: In member function 'bool Calculator::is_trig_command() const':  
Calculator.cpp: error: switch quantity not an integer  
Calculator.cpp: error: 'Calculator::TAN' cannot appear in a constant-expression  
Calculator.cpp: error: 'Calculator::SIN' cannot appear in a constant-expression  
Calculator.cpp: error: 'Calculator::COS' cannot appear in a constant-expression  

Die mächtige internet, heißt es strings sind erlaubt zu verwendet werden in switch-Anweisungen.

Danke an alle, ich Schätze Ihre Hilfe.

War es hilfreich?

Lösung

Im switch, der Ausdruck muss von "ein sein integraler Typ oder eines Klassentyps, für den es eine eindeutige Konvertierung in den integrierten Typ gibt "(Zitat VS2008 DOCS).

Eine String -Klasse hat keine "eindeutige Konvertierung in den integralen Typ" wie a char tut.

Als Arbeit:

  1. Ein ... kreieren map<string, int> und schalten Sie den Wert der Karte ein: switch(command_map[command]) `

  2. Einen Satz machen if/else statt switch. Viel nerviger und schwer zu lesen, also würde ich die Kartenroute empfehlen.

Abgesehen davon ist eine noch bessere Lösung für eine solche wirklich komplizierte Logik darin, die Mapping -Lösung zu verbessern, um loszuwerden switch Ganz und stattdessen mit einer Funktionsanalyse: std::map<std::string, functionPointerType>. Für Ihren spezifischen Fall ist es möglicherweise nicht erforderlich, ist aber für eine komplizierte, sehr lange Nachschlaglogik viel schneller.

Andere Tipps

Als die anderen, und der compiler kommentiert, die Saiten sind nicht erlaubt switch.Ich würde einfach verwenden, if

bool Calculator::is_legal_command() const {
    if(command == TAN) return true;
    if(command == SIN) return true;
    if(command == COS) return true;
    if(command == LOG) return true;
    if(command == LOG10) return true;
    return false;
}

Ich glaube nicht, dass das komplizierter, und es ist ungefähr so schnell, wie es könnte.Sie können auch meine makro-Schalter, so dass es wie

bool Calculator::is_legal_command() const {
    sswitch(command)
    {
    scase (TAN):
    scase (SIN):
    scase (COS):
    scase (LOG):
    scase (LOG10):
        return true;

    sdefault():
        return false;
    }
}

(mit break nach einer return ist dead code, und so sollte vermieden werden).

Saiten können nicht in Switch -Anweisungen in C ++ verwendet werden. Sie müssen dies in die Umwandlung machen if/else if, so was:

if (command == "tan")
{
    // ...
}
else if (command == "cos")
{
    // ...
}
// ...

Eher als ein Schalter.

Ich würde ein Befehlsmuster verwenden. Verwenden Sie dann eine std :: map, um den Funktionsnamen dem Befehlsobjekt zuzuordnen.

Etwas wie das:

#include <math.h>
#include <map>
#include <string>
#include <iostream>

class Function
{
    public:
        // Easy public API that just uses the normal function call symantics
        double   operator()(double value)   { return this->doWork(value);}
        virtual ~Function()     {}
    private:
        // Virtual function where the work is done.
        virtual double doWork(double value) = 0;
};

// A sin/cos function
class Sin: public Function      { virtual double doWork(double value)     { return sin(value); } };
class Cos: public Function      { virtual double doWork(double value)     { return cos(value); } };

// A class that holds all the functions.
// A function name is mapped to a function object.
class FuncMap
{
    public:
        FuncMap()
        {
            // Constructor sets up the map
            functions["sin"]    = &sinFunc;
            functions["cos"]    = &cosFunc;
        }
        Function*   getFunction(std::string command) const
        { 
            // Default result not found.
            Function* result    = NULL;
            std::map<std::string, Function*>::const_iterator    find;

            // Look in the map to see if we find the value.
            // If it exists then find will not point at end()
            if ((find = functions.find(command)) != functions.end())
            {
                // Get the pointer to the function
                result  = find->second;
            }
            return result;
        }
    private:
    Sin     sinFunc;
    Cos     cosFunc;

    std::map<std::string, Function*>    functions;
};

// Declaring it globally for ease of use.
FuncMap     functions;


int main()
{
    // SImple example of usage.
    Function*   func    = functions.getFunction("sin");
    if (func == NULL)
    {
        std::cout << "No Function sin()\n";
        exit(1);
    }
    std::cout << "Result: " << (*func)(12.34) << "\n";
}

Ich bin mir nicht sicher, welches mächtige Internet Sie gelesen haben, aber C ++ erlaubt keine Zeichenfolgen in switch Aussagen. (C# tut jedoch.)

Sie müssen Ihre konvertieren switch Aussage an eine Kette von if-else if-else Aussagen, die Gleichheit testen.

Der Compiler -Fehler sagt Ihnen alles, was Sie wissen müssen. In Switch -Anweisungen können nur Integralypen verglichen werden.

Ich bin mir nicht sicher, welches "mächtige Internet" Ihnen etwas anderes gesagt hat, aber es war mächtig falsch.

Saiten können nicht als Konstanten in Switch -Anweisungen in C ++ verwendet werden. Sie können entweder eine Karte verwenden, eine Reihe von IFs oder Sie können sich von der Darstellung Ihrer Befehle als Saiten zu einer Aufzählung bewegen. Analysieren Sie sich einmal von String zu auferlegt und verwenden Sie dann einen Schalter wie jetzt. Beachten Sie, dass Ihre String -Parsen möglicherweise denselben Mechanismus (MAP/IF) erfordern, abhängig von Ihrem Anwendungsfall, bei dem ein Ansatz über den anderen verwendet wird, möglicherweise die Lesbarkeit verbessern. Ich werde nichts darüber sagen, welcher Ansatz lesbarer ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top