3

ばかげた質問かもしれません。文字列変数を使用して実行時に比較演算子を与える方法はありますか?
ベクトルに給与のデータがあるとします。


vector < int > salary;
Input:
salary[i] != /* ==,>,<,>=,<= (any comparison operator)) */ 9000.

上記のように与えられた入力。比較演算子を文字列strに格納します。str =(任意の比較演算子)。ifとswitchなしでこのようにチェックする方法はありますか?


salary str 9000

4

8 に答える 8

15

キーとして演算子文字列を使用し、値として対応する比較操作用の関数オブジェクトを使用してマップを作成できます。


マップの作成:

std::map<std::string, boost::function<bool(int, int)> > ops;
ops["=="] = std::equal_to<int>();
ops["!="] = std::not_equal_to<int>();
ops[">"]  = std::greater<int>();
ops["<"]  = std::less<int>();
ops[">="] = std::greater_equal<int>();
ops["<="] = std::less_equal<int>(); 

それを使用する:

bool resultOfComparison = ops[str](salary[i], 9000);

(完全な実例については、このリンクを参照してください。)


編集:

@sbiが以下のコメントで述べたようにmap[key]、キーが存在しなかった場合、を使用してマップにアクセスするとエントリが作成されます。したがって、it = map.find(key)代わりに使用してください。map.end()結果がキーと等しい場合は見つかりませんでした。それ以外の場合、値はit->secondです。このソリューションをニーズに適合させる際は、このことに注意してください。

于 2010-10-21T13:01:02.460 に答える
1

それでも、std::map文字列の内容と演算子へのポインタの間にマッピングがある場合があります。

于 2010-10-21T13:00:34.520 に答える
0

いいえ、できません。指定された入力を解析して、対応する操作を呼び出さない限り。いずれにせよ、if-elseステートメントが必要になります。

于 2010-10-21T12:58:52.843 に答える
0

文字列を評価するプログラミング言語には、ある種のEVALが必要です。

編集:C++にはあなたの目的をサポートするEVALがありません。

于 2010-10-21T12:58:57.677 に答える
0

いいえ、C++のようなコンパイル言語はそのようには機能しません。比較を行う最終的な実行可能ファイルにはコードが含まれている必要があります。設計上、C ++は、実際にソースプログラムに含まれていない限り、そのコードを生成しません。

于 2010-10-21T13:00:22.977 に答える
0

文字列をコンストラクターまたはファクトリーとして使用するファンクターを作成して、さまざまなファンクターを生成することもできます(必要な柔軟性に応じて)。

だから次のようなもの:

:入力Comp cmp = Comp(str);

if(cpm(salary [i]、9000)){cout << "wow"; }

于 2010-10-21T13:18:02.813 に答える
0

この必要な評価を「ハック」する必要があります。;)すなわち

template <typename T>
bool eval_op(const string& op, const T& lhs, const T& rhs)
{
  switch(op.size())
  {
    case 2:
    {
      switch(op[1])
      {
        case '=':
        {
          switch(op[0])
          {
            case '=': return lhs == rhs;
            case '!': return lhs != rhs;
            case '>': return lhs >= rhs;
            case '<': return lhs <= rhs;
          }
        }
        default: throw("crazy fool!");
      };
    }
    case 1:
    {
      switch(op[0])
      {
        case '>': return lhs > rhs;
        case '<': return lhs < rhs;
        default: throw ("crazy fool!");
      }
    }
    default: throw ("crazy fool!");
  }

  return false;
}

免責事項:私はこれをテストしていません...しかし、それはアイデアです...

于 2010-10-21T13:18:49.363 に答える
0

この特定の状況では、if-elseブランチが最も簡単なソリューションです。これは単に、比較の選択肢が非常に多く、他に存在しないことを確信できるからです。本質的に、あなたのコードは次の行に沿っている必要があります

if( in == "==" )
    cond = salary[i] == 9000;
else if( in == "!=" )
    cond = salary[i] != 9000;
// ...
else
  // throw, return -1, raise a flag or burst out in laughter

eval()ここでは入力をサニタイズするため、これは実際にはダイナミックよりも安全です。Little Bobby Tablesの攻撃に沿って、悪意のあるコードがそこにないことを確認します。

確かに、ここではポリモーフィズムを使用できますが、ポリモーフィズムのポイントは、オープンエンドタイプの代替をサポートすることです。ケースを追加したい場合、ポリモーフィズムを使用すると簡単に追加できます。しかし、基礎を築くためにいくつかの作業を行う必要があります。ここでは、正確に6つの比較の選択肢があります。または、任意の述語のサポートを追加する場合は7。

于 2010-10-21T13:35:00.750 に答える