views:

151

answers:

8
A: 

No. Not possible. Unless you parse the given input and call the corresponding operation. In any case, you would need a if - else statement.

Prabhu
"In any case, you would need an if-else statement". No you wouldn't.
wilhelmtell
A: 

You need to have something of sort of EVAL in your programming language, which evaluates your strings.

EDIT: C++ does not have EVAL to support your cause.

Sachin Shanbhag
There is no eval in vanilla c++
sum1stolemyname
"Most programming languages have eval" is a gross exaggeration. It exists in only a fraction of languages. Also, C++ doesn't have it.
Matti Virkkunen
Edited the answer as per comments obtained.
Sachin Shanbhag
A: 

No, compiled languages like C++ don't work like that. There has to be code in the final executable that does the comparison, and by design C++ doesn't generate that code unless it's actually in the source program.

unwind
+1  A: 

Still, you might have a std::map with a mapping between contents of your strings and pointers to your operators.

Benoit
can you elaborate with simple example??
jony
see missingfaktor's answer :)
Benoit
+14  A: 

You can create a map with operator-strings as keys and function objects for corresponding comparison operations as values.


Creating a map:

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>(); 

Using it:

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

(See this link for a complete working example.)


EDIT:

As @sbi said in the comments below, accessing a map using map[key] will create an entry if the key didn't exist. So use it = map.find(key) instead. If the result is equal to map.end() the key wasn't found, otherwise value is it->second. Take note of this while adapting this solution to your needs.

missingfaktor
`ops["=="] = std::equal_to<int>();`
sbi
Also, note that accessing a map using `map[key]` will create an entry if the `key` didn't exist. Often you don't want that. Use `it = map.find(key)` instead. If the result is equal to `map.end()` the key wasn't found, otherwise value is `it->second`.
sbi
@sbi: Thanks for the tips. Edited. :)
missingfaktor
yes.. thanks for the answer.
jony
@Jony: Welcome. Sidenote: You should start accepting answers to your questions. (You can refer to [this thread](http://meta.stackoverflow.com/questions/5234/how-does-accepting-an-answer-work) on meta if you don't know how to do that.)
missingfaktor
@missingfaktor - thanks for the link and for the answer ;)
jony
@missingfaktor - Can we do this without boost library
jony
@Jony: Yes. You can use [`std::tr1::function`](http://www.drdobbs.com/184401949;jsessionid=WCG3HPFYZJNPLQE1GHRSKH4ATMY32JVN) instead of `boost::function`.
missingfaktor
A: 

You can also create a functor which will take string as a constructor or factory which will produce different functors (depending on flexibility you need).

So something like:

:Input Comp cmp = Comp(str);

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

Gregory
A: 

You'd have to "hack" in this required eval! ;) i.e.

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;
}

DISCLAIMER: I've not tested this... but it's an idea...

Nim
A: 

In this particular situation an if-else branch is your simplest solution. This is simply because there are only so many comparison alternatives, and you can be sure none others will ever exist. In essence your code should be along the lines of

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

This is in fact safer than a dynamic eval() because here you sanitize the input. You make sure there is no malicious code in there, along the lines of a Little Bobby Tables attack.

Granted, you could use polymorphism here, but the point of polymorphism is support open-ended type alternatives. When you wish to add a case, polymorphism allows you to do that with ease. But you'd need to do some work to get foundations up, and here there are exactly 6 comparison alternatives. Or 7, if you want to add support for an arbitrary predicate.

wilhelmtell