How to convert string to operator

S

shsingh

I have a function which takes two operands (char*) and a operator
(char*)

int myFunc(char* operand1, char* operand2, char* myoperator);

Depending upon the operator, i want to do the manipulation on both
operands. I dont want to hardcode the operator values or use of switch/
if-else statement to determine the operation.
Is there any way to solve this problem ??
 
?

=?iso-8859-1?q?Erik_Wikstr=F6m?=

I have a function which takes two operands (char*) and a operator
(char*)

int myFunc(char* operand1, char* operand2, char* myoperator);

Depending upon the operator, i want to do the manipulation on both
operands. I dont want to hardcode the operator values or use of switch/
if-else statement to determine the operation.
Is there any way to solve this problem ??

I'm not quite sure what the function is supposed to do, if it performs
mathematical computations you probably want to use int or double
instead of char, and passing by reference would be better. If it
works on strings you should try to use strings instead of char*.

Anyway, the best way might be to pass the operator as either a type or
an object which performs the operation (note that this just means that
you'll have to have the switch statement somewhere else, you can't get
rid of it).
 
V

V.R. Marinov

I have a function which takes two operands (char*) and a operator
(char*)

int myFunc(char* operand1, char* operand2, char* myoperator);

Depending upon the operator, i want to do the manipulation on both
operands. I dont want to hardcode the operator values or use of switch/
if-else statement to determine the operation.
Is there any way to solve this problem ??


In C++ there are at least two ways to get rid of a switch:
- Factory design pattern
- Array of pointers to functions

Since you are not concerned with objects and classes
the more suitable solution would be to use an array of
function pointers.
 
D

Dizzy

V.R. Marinov said:
In C++ there are at least two ways to get rid of a switch:
- Factory design pattern
- Array of pointers to functions

I will also add the "simple" (yet overlooked) function overloading. Many
people prefer things of the form:
int dostuff(int mode, /*other params*/)
{
switch(mode){
case func1: dofunc1(); break;
case func2: dofunc2(); break;
...
}
}

Even when mode is not runtime decided but compile time decided (like APIs
for opening files and having the READ mode, WRITE mode open flag but
knowing at compile time how you want to open it and having it always called
like "open("file", O_READ)") they write stuff like that. When they can use
overloading to have the compiler determine the function to actually execute
at compile time and also get a compile time error if trying to use an
unknown "mode" (instead of a runtime error). ie do something like:
int dostuff(read_mode_t const&, /*other params*/);
int dostuff(write_mode_t const&, /*other params*/);

And have the caller just write "dostuff(read_mode, params);".

PS: in that example read_mode is a static instance of read_mode_t declared
somewhere; it's irrelevant to what contents read_mode_t has, it only
matters it's type and we (ab)use this to have the compiler overloading
lookup mechanism find the apropriate code at compile time
 
V

V.R. Marinov

I will also add the "simple" (yet overlooked) function overloading. Many
people prefer things of the form:
int dostuff(int mode, /*other params*/)
{
switch(mode){
case func1: dofunc1(); break;
case func2: dofunc2(); break;
...
}

}

Even when mode is not runtime decided but compile time decided (like APIs
for opening files and having the READ mode, WRITE mode open flag but
knowing at compile time how you want to open it and having it always called
like "open("file", O_READ)") they write stuff like that. When they can use
overloading to have the compiler determine the function to actually execute
at compile time and also get a compile time error if trying to use an
unknown "mode" (instead of a runtime error). ie do something like:
int dostuff(read_mode_t const&, /*other params*/);
int dostuff(write_mode_t const&, /*other params*/);

And have the caller just write "dostuff(read_mode, params);".


Good point! There is no reason why compile-time constants
should be handled at run-time.

PS: in that example read_mode is a static instance of read_mode_t declared
somewhere; it's irrelevant to what contents read_mode_t has, it only
matters it's type and we (ab)use this to have the compiler overloading
lookup mechanism find the apropriate code at compile time


Btw there is another (less efficient) way to the same thing.


//header file + namespace

enum Choice { ADD = '+', MUL = '*' };

template<int T> struct DoStuff{};

template<>
struct DoStuff<'+'>
{
const int Result(){ return result; }
DoStuff(int a, int b):result(a+b){}
private:
int result;
};


template<>
struct DoStuff<'*'>
{
const int Result(){ return result; }
DoStuff(int a, int b):result(a*b){}
private:
int result;
};

//main.cpp

int main()
{
cout << DoStuff<ADD>(5, 2).Result() << endl;
cout << DoStuff<'*'>(5, 2).Result() << endl;
}


Probably if no return type for DoStuff() is required
this approach might be usefull in a way.
 
T

Thomas J. Gritzan

shsingh said:
I have a function which takes two operands (char*) and a operator
(char*)

int myFunc(char* operand1, char* operand2, char* myoperator);

I would suggest either 'const char*' or 'const std::string&' here.
Depending upon the operator, i want to do the manipulation on both
operands. I dont want to hardcode the operator values or use of switch/
if-else statement to determine the operation.
Is there any way to solve this problem ??

A mapping from strings to code.

The mapping is easy: Use a std::map<std::string, XXXX>.
You can easily call the code that handles your operator.

For the actual code you have some options:
1) function pointers, so your map becomes:

typedef int operation_t(const char*, const char*);
std::map<std::string, operation_t> operators;

2) Command design pattern:
You put a base class pointer into the map, and the subclasses define the
code that handles your operator.

3) Instead of raw function pointers,
use a boost::function<> (or std::tr1::function<>).
So you also can use a member function bound to an object as handler.
 
J

James Kanze

V.R. Marinov wrote:
I will also add the "simple" (yet overlooked) function overloading. Many
people prefer things of the form:
int dostuff(int mode, /*other params*/)
{
switch(mode){
case func1: dofunc1(); break;
case func2: dofunc2(); break;
...
}
}
Even when mode is not runtime decided but compile time decided (like APIs
for opening files and having the READ mode, WRITE mode open flag but
knowing at compile time how you want to open it and having it always called
like "open("file", O_READ)") they write stuff like that. When they can use
overloading to have the compiler determine the function to actually execute
at compile time and also get a compile time error if trying to use an
unknown "mode" (instead of a runtime error). ie do something like:
int dostuff(read_mode_t const&, /*other params*/);
int dostuff(write_mode_t const&, /*other params*/);
And have the caller just write "dostuff(read_mode, params);".
PS: in that example read_mode is a static instance of read_mode_t declared
somewhere; it's irrelevant to what contents read_mode_t has, it only
matters it's type and we (ab)use this to have the compiler overloading
lookup mechanism find the apropriate code at compile time

I thought that the canonical solution for that was to use
distinct enum types, e.g.:

enum ReadMode { read } ;
enum WriteMode { write } ;

void doStuff( ReadMode, ... ) ;
void doStuff( WriteMode, ... ) ;

At least, that was the way I learned it when I was learning C++.
(It was very, very frequent then to simulate "explicit", e.g.:

enum ExplicitCtor { constructWith } ;

class IntArray
{
public:
IntArray( ExplicitCtor, size_t size ) ;
// ...
} ;

to avoid accidental conversions.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,293
Messages
2,571,504
Members
48,190
Latest member
Alisnrob

Latest Threads

Top