エラー:整数ではなくスイッチ数量
-
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
Mighty Internetは、文字列をスイッチステートメントで使用できると書かれています。
みなさん、ありがとう、私はあなたの助けに感謝します。
解決
の switch
, 、表現は「an」でなければなりません 積分タイプ または、積分タイプへの明確な変換があるクラスタイプ」(VS2008ドキュメントの引用).
文字列クラスには、「積分タイプへの明確な変換」がありません。 char
します。
回避策として:
aを作成します
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
平等をテストするステートメント。
コンパイラエラーは、知る必要があるすべてのことを示します。スイッチステートメントでは、積分タイプのみを比較できます。
どの「Mighty Internet」があなたに言ったかはわかりませんが、それは強大な間違っていました。
文字列は、C ++のスイッチステートメントの定数として使用することはできません。マップ、一連のIFのものを使用するか、コマンドを文字列として表現することから列挙に移動できます。文字列から列挙に一度解析してから、今のようにスイッチを使用します。文字列の解析には、同じメカニズム(Map/if's)が必要になる場合があることに注意してください。ただし、1つのアプローチを使用して他のアプローチを使用する場合は、読みやすさを改善する場合があります。どのアプローチがより読みやすいかについては何も言うつもりはありません。