我已经在StackOverflow和多谷歌链接上研究了我的问题,我仍然感到困惑。我认为对我来说最好的事情就是问......
我正在创建一个简单的命令行计算器。到目前为止,这是我的代码:
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语句中使用字符串。
谢谢大家,感谢您的帮助。
答案 0 :(得分:17)
在switch
中,表达式必须是“integral type或类型类型,其明确转换为整数类型”(quoting VS2008 docs)。
字符串类没有“明确转换为整数类型”,就像char
那样。
作为一种解决方法:
创建map<string, int>
并启用地图的值:switch(command_map[command])
`
执行一组if
/ else
而不是切换。更烦人,更难阅读,所以我推荐地图路线。
顺便说一句,对于那种非常复杂的逻辑来说,更好的解决方案是改进映射解决方案以完全摆脱switch
,而不是使用函数查找:std::map<std::string, functionPointerType>
。对于您的特定情况可能不需要它,但对于复杂的非常长的查找逻辑来说,速度要快得多。
答案 1 :(得分:9)
正如其他人和编译器所评论的那样,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;
}
我认为这并不复杂,而且它的速度和它一样快。您也可以使用我的switch macro,使其看起来像
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
为死代码,因此应避免使用。
答案 2 :(得分:2)
字符串不能在C ++中的switch语句中使用。您需要将其转换为if
/ else if
,如下所示:
if (command == "tan")
{
// ...
}
else if (command == "cos")
{
// ...
}
// ...
答案 3 :(得分:2)
而不是开关。
我会使用命令模式。然后使用std :: map将函数名映射到命令对象。
这样的事情:
#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";
}
答案 4 :(得分:1)
不确定您正在阅读哪个强大的互联网,但C ++不允许在switch
语句中使用字符串。 (不过,C#确实如此。)
您需要将switch
语句转换为测试相等性的if
- else if
- else
个语句链。
答案 5 :(得分:1)
编译器错误告诉您需要知道的一切。在switch语句中只能比较整数类型。
我不确定哪个“强大的互联网”告诉你,但这是错误的。
答案 6 :(得分:0)
在c ++的switch语句中,字符串不能用作常量。您既可以使用地图,也可以使用一系列if,或者可以将命令作为字符串表示为枚举。从字符串解析为枚举一次,然后使用像现在这样的开关。请注意,您的字符串解析可能需要相同的机制(map / if's),但根据您的使用情况,使用一种方法而不是另一种方法可能会提高可读性。我不打算说哪种方法更具可读性。