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]如果密钥不存在,访问地图 using 将创建一个条目。所以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

您还可以创建一个仿函数,它将字符串作为构造函数或工厂,它将产生不同的仿函数(取决于您需要的灵活性)。

所以像:

:输入比较 cmp = Comp(str);

if (cpm(salary[i], 9000)) { cout << "哇"; }

于 2010-10-21T13:18:02.813 回答
0

你必须在这个必需的评估中“破解”!;) IE

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 回答