C++ 错误:开关数量不是整数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4535825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
error: switch quantity not an integer
提问by Ken
I have researched my issue all over StackOverflow and multi-google links, and I am still confused. I figured the best thing for me is ask...
我已经通过 StackOverflow 和多谷歌链接研究了我的问题,但我仍然感到困惑。我想对我来说最好的事情是问...
Im creating a simple command line calculator. Here is my code so far:
我正在创建一个简单的命令行计算器。到目前为止,这是我的代码:
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
The mighty internet, it says strings are allowed to be used in switch statements.
强大的互联网,它说允许在 switch 语句中使用字符串。
Thanks everyone, I appreciate your help.
谢谢大家,我感谢你的帮助。
回答by DVK
In switch
, the expression must be of "an integral typeor of a class type for which there is an unambiguous conversion to integral type" (quoting VS2008 docs).
在 中switch
,表达式必须是“一个整数类型或一个可以明确转换为整数类型的类类型”(引用 VS2008 文档)。
A string class doesn't have "unambiguous conversion to integral type", like a char
does.
字符串类不像 a 那样具有“明确转换为整数类型” char
。
As a work-around:
作为解决方法:
Create a
map<string, int>
and switch on the value of the map:switch(command_map[command])
`Do a set of
if
/else
instead of switch. Much more annoying and hard to read, so I'd recommend the map route.
创建一个
map<string, int>
并打开地图的值:switch(command_map[command])
`做一组
if
/else
而不是 switch。更烦人且难以阅读,所以我推荐地图路线。
As an aside, an even better solution for really complicated logic like that is to improve the mapping solution to get rid of switch
completely and instead go with a function lookup: std::map<std::string, functionPointerType>
. It may not be needed for your specific case, but is MUCH faster for complicated very long look-up logic.
顺便说一句,对于真正复杂的逻辑,一个更好的解决方案是改进映射解决方案以switch
完全摆脱,而是使用函数查找:std::map<std::string, functionPointerType>
. 对于您的特定情况可能不需要它,但对于复杂的超长查找逻辑要快得多。
回答by Johannes Schaub - litb
As others and the compiler commented, strings are not allowed with switch
. I would just use if
正如其他人和编译器所评论的那样,字符串不允许使用switch
. 我只会用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 that's any more complicated, and it's about as fast as it could get. You could also use my switch macro, making it look like
我不认为这更复杂,而且速度很快。你也可以使用我的switch 宏,让它看起来像
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 a return
is dead code, and so should be avoided).
(break
在 a 之后return
是死代码,因此应该避免)。
回答by Martin York
Rather than a switch.
而不是一个开关。
I would use a command pattern. Then use a std::map to map the function name to the command object.
我会使用命令模式。然后使用 std::map 将函数名称映射到命令对象。
Something like this:
像这样的东西:
#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";
}
回答by SoapBox
Strings cannot be used in switch statements in C++. You'll need to turn this into if
/else if
, like this:
字符串不能在 C++ 的 switch 语句中使用。你需要把它变成if
/ else if
,像这样:
if (command == "tan")
{
// ...
}
else if (command == "cos")
{
// ...
}
// ...
回答by Adam Maras
Not sure which mighty Internet you've been reading, but C++ doesn't allow strings in switch
statements. (C# does, though.)
不确定您读过哪个强大的 Internet,但 C++ 不允许在switch
语句中使用字符串。(不过,C# 确实如此。)
You need to convert your switch
statement to a chain of if
-else if
-else
statements that test equality.
您需要将转换switch
语句链if
- else if
-else
语句测试平等。
回答by Lightness Races in Orbit
The compiler error tells you everything you need to know. Only integral types may be compared in switch statements.
编译器错误告诉您需要知道的一切。在 switch 语句中只能比较整数类型。
I'm not sure which "mighty internet" told you otherwise, but it was mighty wrong.
我不确定哪个“强大的互联网”告诉你否则,但这是大错特错。
回答by villintehaspam
Strings cannot be used as constants in switch statements in c++. You can either use a map, a series of if's or you can move from representing your commands as strings to an enum. Parse from string to enum once, then use a switch like you do now. Note that your string parsing may require the same mechanism (map/if's), but depending on your use case using one approach over the other may improve readability. I'm not going to say anything on which approach is more readable.
字符串不能用作 C++ 中 switch 语句中的常量。您可以使用映射、一系列 if,也可以从将命令表示为字符串转移到枚举。从字符串解析为枚举一次,然后像现在一样使用开关。请注意,您的字符串解析可能需要相同的机制(map/if),但根据您的用例,使用一种方法而不是另一种方法可能会提高可读性。我不会说哪种方法更具可读性。