这可能是个愚蠢的问题。有没有办法在运行时使用字符串变量给比较运算符。
假设我有一个向量中的工资数据。
vector < int > salary;
Input:
salary[i] != /* ==,>,<,>=,<= (any comparison operator)) */ 9000.
上面给出的输入。我将比较运算符存储在字符串 str 中。str =(任何比较运算符)。有没有什么方法可以在没有 if 和 switch 的情况下进行检查。
salary str 9000
这可能是个愚蠢的问题。有没有办法在运行时使用字符串变量给比较运算符。
假设我有一个向量中的工资数据。
vector < int > salary;
Input:
salary[i] != /* ==,>,<,>=,<= (any comparison operator)) */ 9000.
上面给出的输入。我将比较运算符存储在字符串 str 中。str =(任何比较运算符)。有没有什么方法可以在没有 if 和 switch 的情况下进行检查。
salary str 9000
您可以创建一个映射,其中操作符字符串作为键,函数对象用于相应的比较操作作为值。
创建地图:
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
。请注意这一点,同时根据您的需求调整此解决方案。
不过,您可能std::map
在字符串内容和指向运算符的指针之间有一个映射。
不,不可能。除非您解析给定的输入并调用相应的操作。在任何情况下,您都需要一个 if - else 语句。
您需要在您的编程语言中使用某种 EVAL 来评估您的字符串。
编辑:C++ 没有 EVAL 来支持您的事业。
不,像 C++ 这样的编译语言不能那样工作。最终的可执行文件中必须有代码进行比较,并且根据设计,C++ 不会生成该代码,除非它实际上在源程序中。
您还可以创建一个仿函数,它将字符串作为构造函数或工厂,它将产生不同的仿函数(取决于您需要的灵活性)。
所以像:
:输入比较 cmp = Comp(str);
if (cpm(salary[i], 9000)) { cout << "哇"; }
你必须在这个必需的评估中“破解”!;) 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;
}
免责声明:我没有测试过这个......但这是一个想法......
在这种特殊情况下,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,如果您想添加对任意谓词的支持。