Error: the number of switches is not an integer

I researched my problem on all the StackOverflow and multi-google links, and I'm still confused. I thought the best thing for me is to ask ...

I am creating a simple command line calculator. Here is my code:

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

the error i get 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 

Powerful internet, he says that strings can be used in switch statements.

Thanks to everyone, I appreciate your help.

+6
c ++ string switch-statement constant-expression
source share
7 answers

In switch expression should be " an integer type or a class type for which there is an unambiguous conversion to an integral type" ( citing VS2008 documents ).

The string class does not have "unambiguous conversion to integral type", as char does.

As a workaround:

  • Create map<string, int> and enable the map value: switch(command_map[command]) `

  • Make an if / else set instead. Much more annoying and hard to read, so I would recommend a map route.

As an aside, an even better solution for really complex logic is to improve the display solution in order to completely get rid of the switch and instead go to the function search: std::map<std::string, functionPointerType> . This may not be necessary for your particular case, but much faster for complex, very long search logic.

+15
source share

Like others, and the compiler comments, lines are not allowed with switch . I would just use 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; } 

I don’t think it’s more complicated, and it’s about as fast as it could be. You can also use my macro to make it look like

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

(having break after return dead code, and therefore should be avoided).

+8
source share

Strings cannot be used in switch statements in C ++. You will need to turn this into if / else if , for example:

 if (command == "tan") { // ... } else if (command == "cos") { // ... } // ... 
+2
source share

Instead of a switch.

I would use the command template. Then use std :: map to map the function name to the command object.

Something like that:

 #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"; } 
+2
source share

Not sure how powerful Internet you read, but C ++ doesn't allow strings in switch . (However, C #).

You need to convert the switch to a chain of if - else if - else that check for equality.

+1
source share

A compiler error tells you everything you need to know. In switch statements, only integral types can be compared.

I’m not sure what “powerful Internet” told you otherwise, but it wasn’t.

+1
source share

Strings cannot be used as constants in switch statements in C ++. You can use a map, an if series, or you can go from representing your commands as strings to listing. Parse from a string in enum once, then use the switch as you are doing now. Please note that parsing the strings may require the same mechanism (map / if's), but depending on your use case, using one approach over another can improve readability. I am not going to say anything about which approach is more readable.

0
source share

All Articles