错误:开关数量不是整数
-
13-10-2019 - |
题
我已经研究了整个Stackoverflow和Multi-Google链接的问题,但我仍然感到困惑。我认为对我来说最好的是问...
我创建一个简单的命令行计算器。到目前为止,这是我的代码:
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;
}
}
我得到的错误是:
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
它说,强大的互联网说,允许字符串在交换机语句中使用。
谢谢大家,感谢您的帮助。
解决方案
在 switch
, ,表达必须是“ 积分类型 或一个类型的类型,该类型有明确转换为积分类型的“(引用VS2008文档).
字符串类没有“明确转换为积分类型”,例如 char
做。
作为一个工作:
创建一个
map<string, int>
并打开地图的值:switch(command_map[command])
`做一套
if
/else
而不是切换。更令人讨厌且难以阅读,所以我建议您使用地图路线。
顺便说一句,这样的真正复杂逻辑的更好解决方案是改善映射解决方案以摆脱 switch
完全使用功能查找: std::map<std::string, functionPointerType>
. 。对于您的特定情况可能不需要,但是对于复杂的非常长的查找逻辑而言,它更快。
其他提示
正如其他人和编译器所评论的那样,不允许使用字符串 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;
}
我认为这还不再复杂,而且可能会得到尽可能快的速度。你也可以使用我的 切换宏, ,使它看起来像
bool Calculator::is_legal_command() const {
sswitch(command)
{
scase (TAN):
scase (SIN):
scase (COS):
scase (LOG):
scase (LOG10):
return true;
sdefault():
return false;
}
}
(有 break
之后 return
是死亡代码,因此应避免)。
字符串不能在C ++中的开关语句中使用。您需要将其变成 if
/else if
, , 像这样:
if (command == "tan")
{
// ...
}
else if (command == "cos")
{
// ...
}
// ...
而不是开关。
我会使用命令模式。然后使用std ::映射将函数名称映射到命令对象。
这样的事情:
#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";
}
不确定您一直在阅读哪种强大的互联网,但是C ++不允许字符串 switch
语句。 (c#确实。)
您需要转换您的 switch
链条 if
-else if
-else
测试平等的语句。
编译器错误告诉您您需要了解的所有内容。在开关语句中只能比较积分类型。
我不确定哪个“强大的互联网”告诉您,但这是错误的。
在C ++中的开关语句中不能将字符串用作常量。您可以使用地图,一系列IF,也可以从表示命令作为字符串转变为枚举。从字符串到枚举一次,然后像现在这样使用开关。请注意,您的字符串解析可能需要相同的机制(MAP/IF),但是根据您的用例,使用一种方法可以提高可读性。我不会说什么方法更可读。