fout: wissel hoeveelheid geen geheel getal

Ik heb mijn probleem overal in StackOverflow en multi-google-links onderzocht, en ik ben nog steeds in de war. Ik dacht dat ik het het beste kon vragen…

Ik ben een eenvoudige opdrachtregelcalculator aan het maken. Dit is mijn code tot nu toe:

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;
    }
}

de fout die ik krijg is:

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  

Het machtige internet, het zegt dat strings mogen worden gebruikt in switch-statements.

Iedereen bedankt, ik waardeer jullie hulp.


Antwoord 1, autoriteit 100%

In switchmoet de uitdrukking “an integraaltypeof van een klassetype waarvoor een ondubbelzinnige conversie naar integraaltype bestaat” (met vermelding van VS2008-documenten).

Een tekenreeksklasse heeft geen “ondubbelzinnige conversie naar integraal type”, zoals een chardat wel heeft.

Als tijdelijke oplossing:

  1. Maak een map<string, int>en schakel de waarde van de kaart in: switch(command_map[command])
    `

  2. Voer een reeks if/elseuit in plaats van te wisselen. Veel vervelender en moeilijker te lezen, dus ik raad de kaartroute aan.

Terzijde, een nog betere oplossing voor echt gecompliceerde logica zoals deze is om de mapping-oplossing te verbeteren om switchvolledig te verwijderen en in plaats daarvan een functie-lookup te gebruiken: std::map<std::string, functionPointerType>. Het is misschien niet nodig voor uw specifieke geval, maar is VEEL sneller voor gecompliceerde, zeer lange opzoeklogica.


Antwoord 2, autoriteit 40%

Zoals anderen en de compiler opmerkten, zijn strings niet toegestaan met switch. Ik zou gewoon if

. gebruiken

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;
}

Ik denk niet dat het ingewikkelder is, en het is ongeveer zo snel als maar kan. Je kunt ook mijn schakelmacrogebruiken, zodat het lijkt leuk vinden

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

(breakna een returnis dode code, en moet dus worden vermeden).


Antwoord 3, autoriteit 12%

Strings kunnen niet worden gebruikt in switch-statements in C++. Je moet dit veranderen in if/else if, zoals dit:

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

Antwoord 4, autoriteit 12%

Ik weet niet zeker welk machtige internet je hebt gelezen, maar C++ staat geen strings toe in switch-statements. (C# wel.)

U moet uw switch-statement converteren naar een reeks ifelse ifelse-statements die gelijkheid testen.


Antwoord 5, autoriteit 8%

In plaats van een schakelaar.

Ik zou een opdrachtpatroon gebruiken. Gebruik dan een std::map om de functienaam toe te wijzen aan het opdrachtobject.

Zoiets:

#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";
}

Antwoord 6, autoriteit 8%

De compilerfout vertelt je alles wat je moet weten. Alleen integrale typen mogen worden vergeleken in schakelinstructies.

Ik weet niet zeker welk ‘machtig internet’ je iets anders heeft verteld, maar het was helemaal verkeerd.


Antwoord 7, autoriteit 4%

Strings kunnen niet worden gebruikt als constanten in switch-statements in c++. Je kunt ofwel een kaart gebruiken, een reeks als’s of je kunt overstappen van het weergeven van je commando’s als strings naar een opsomming. Ontleed één keer van string naar enum en gebruik dan een schakelaar zoals je nu doet. Houd er rekening mee dat voor het parseren van strings mogelijk hetzelfde mechanisme (map/if’s) nodig is, maar afhankelijk van uw gebruikssituatie kan het gebruik van de ene benadering boven de andere de leesbaarheid verbeteren. Ik ga niets zeggen over welke aanpak beter leesbaar is.

Other episodes