15

我已经通过 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 语句中使用字符串。

谢谢大家,我很感激你的帮助。

4

7 回答 7

25

switch中,表达式必须是“整数类型或具有明确转换为整数类型的类类型”(引用 VS2008 文档)。

字符串类没有像 achar那样“明确转换为整数类型”。

作为一种解决方法:

  1. 创建一个map<string, int>并打开地图的值:switch(command_map[command]) `

  2. 做一组if/else代替 switch。更烦人且难以阅读,所以我推荐地图路线。

顺便说一句,对于真正复杂的逻辑,一个更好的解决方案是改进映射解决方案以完全摆脱它,switch而是使用函数查找:std::map<std::string, functionPointerType>. 您的特定情况可能不需要它,但对于复杂的非常长的查找逻辑要快得多。

于 2010-12-26T23:27:25.807 回答
11

正如其他人和编译器所评论的那样,字符串不允许使用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 宏,让它看起来像

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

    sdefault():
        return false;
    }
}

break在 a 之后return是死代码,因此应该避免)。

于 2010-12-27T00:03:53.380 回答
3

字符串不能在 C++ 的 switch 语句中使用。您需要将其转换为if/ else if,如下所示:

if (command == "tan")
{
    // ...
}
else if (command == "cos")
{
    // ...
}
// ...
于 2010-12-26T23:25:31.090 回答
3

不确定您一直在阅读哪个强大的 Internet,但 C++ 不允许在switch语句中使用字符串。(不过,C# 确实如此。)

您需要将您的switch语句转换为一串测试相等ifelse ifelse语句。

于 2010-12-26T23:26:29.297 回答
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";
}
于 2010-12-27T00:37:05.380 回答
2

编译器错误告诉你你需要知道的一切。在 switch 语句中只能比较整数类型。

我不确定哪个“强大的互联网”告诉你,但这是非常错误的。

于 2011-01-02T22:53:11.470 回答
1

字符串不能用作 c++ 中 switch 语句中的常量。您可以使用映射、一系列 if,也可以从将命令表示为字符串转换为枚举。从字符串解析到枚举一次,然后像现在一样使用开关。请注意,您的字符串解析可能需要相同的机制(map/if's),但根据您的用例,使用一种方法而不是另一种方法可能会提高可读性。我不会说哪种方法更具可读性。

于 2010-12-26T23:26:30.607 回答