Adding the ! operator and sqrt(), pow(), etc. to a calculator example application

  1. There are a few solutions posted on Stroustrup - Programming and more will be coming over time.

  2. Try solving exercises only with the language features and the library facilities presented so far in the book -- real novice users can't do anything else. Then return later to see how a solution can be improved.


I thought a map of strings to function pointers might be a concise way to represent things like sqrt, sin, cos, etc. that take a single double and return a double:

map<std::string, double (*)(double)> funcs;
funcs["sqrt"] = &sqrt;
funcs["sin"] = &sin;
funcs["cos"] = &cos;

Then when the parser detects a correct string (str) it can call the function with an argument (arg) like so:

double result = funcs[str](arg);

With this method, a single call can handle all cases of functions (of that type).

Actually I'm not sure if that's the correct syntax, can anyone confirm?

Does this seem like a usable method?


It is easier to work with derived classes and virtual functions: each specialized class reading its own input...

class base {
    public:
        virtual double calc() = 0;
};

class get_sqrt : public base {
    int useless;

    public:
        virtual double calc() {
            cin >> number;
            return sqrt(number);
        }
}

get_sqrt;

Now we organize these in a map, and we will only use their pointers:

map<string,base*> func;
func["sqrt"] = &get_sqrt;

There is also a specialized method which only looks at the next character: peek();

char c = cin.peek();

You can get rid of the switch by using 1 if putting !, +, -, etc. in func; (they should operate on left_param for simplicity):

 if (c>='0' && c<='9')
     cin >> right_param; // Get a number, you don't have to put the
                         // character back as it hasn't been removed
 else {
     string s;
     cin >> s;
     right_param = func[s]->calc();
 }

So basically some kind of function pointers, but without the messy syntax and in which you could store data between calculations.

I thought about the whitespace problem; it can be added before it starts to compute, I also think there could be a way to set different separators, like numbers, but I don't know how.

Tags:

C++