Erreur: Quantité de commutation pas un nombre entier
-
13-10-2019 - |
Question
J'ai étudié mon problème partout dans StackOverflow et des liens multi-google, et je suis encore confus. Je me suis dit que la meilleure chose pour moi est de demander ...
Im la création d'une simple calculatrice de ligne de commande. Voici mon code à ce jour:
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;
}
}
l'erreur que je reçois est:
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
L'Internet puissant, il dit les chaînes sont autorisés à être utilisés dans les états de commutation.
Merci à tous, je vous remercie de votre aide.
La solution
Dans switch
, l'expression doit être « type intégral ou d'un type de classe pour laquelle il y a une conversion non ambiguë du type intégral "(
Autres conseils
Comme d'autres et le compilateur commenté, les chaînes ne sont pas autorisés avec switch
. Je voudrais simplement utiliser 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;
}
Je ne pense pas que ce soit plus compliqué, et il est à peu près aussi vite que cela pourrait arriver. Vous pouvez également utiliser mon commutateur macro, faisant paraître comme
bool Calculator::is_legal_command() const {
sswitch(command)
{
scase (TAN):
scase (SIN):
scase (COS):
scase (LOG):
scase (LOG10):
return true;
sdefault():
return false;
}
}
(ayant break
après un return
est le code mort, et doit donc être évitée).
Les chaînes ne peut pas être utilisé dans les états de commutation en C ++. Vous aurez besoin de transformer cela en if
/ else if
, comme ceci:
if (command == "tan")
{
// ...
}
else if (command == "cos")
{
// ...
}
// ...
Au lieu d'un commutateur.
J'utiliser un modèle de commande. Ensuite, utilisez un std :: carte pour mapper le nom de la fonction de l'objet de commande.
Quelque chose comme ceci:
#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";
}
Je ne sais pas qui puissant Internet que vous avez lu, mais C ++ ne permet pas de chaînes dans les instructions switch
. (C # fait, cependant.)
Vous devez convertir votre déclaration de switch
à une chaîne de déclarations if
-else if
-else
que l'égalité de test.
L'erreur du compilateur vous indique tout ce que vous devez savoir. Seuls les types entiers peuvent être comparés dans les états de commutation.
Je ne suis pas sûr « Internet puissant » vous dit le contraire, mais il avait tort puissant.
Les chaînes ne peut pas être utilisé comme des constantes dans les états de commutation en c ++. Vous pouvez utiliser une carte, une série de cas de ou vous pouvez passer de représenter vos commandes sous forme de chaînes à un ENUM. Parse de chaîne à ENUM une fois, puis utiliser un commutateur comme vous le faites maintenant. Notez que votre analyse de chaîne peut exiger le même mécanisme (carte / si son), mais en fonction de votre cas d'utilisation à l'aide d'une approche sur l'autre peut améliorer la lisibilité. Je ne vais pas dire quoi que ce soit sur l'approche est plus lisible.