Gyome
Gyome

Reputation: 1333

Factory of type

In order to create an arithmetic evaluator, I have to create a Factory that would take a string in parameter, and return, depending on the string, a variable of a different type.

Example:

TypeFactory.make("int") return int i=0;
TypeFactory.make("float") return float f=0;

I thought of many different kind of implementation, but none seems to work:

I could make a class Type, and its children Float and Int, that would be returned by the factory, but then how could I get the value in the class in a generic way (like Type.getVal(), it wouldn't exist, so I couldn't use it in the rest of my program)

I hope I'm being clear in my question (it's not even really clear for me!)

Does anyone have some idea? Thanks

EDIT:

As I realise that this question is hard to undestand, I will explain what I have to do in a more general way.

The goal is to evaluate arithmetic expressions from a file. Exemple:

int a;
float b;
float c;
a=1;
b=6;
c=a+b;

that's my file. My program will construct a Tree from those expressions. I use Composite and Visitor patterns for that. But MY problem is, I have to distinguished each types before, to tell which variable is of which type when my visitor do the operations, and be able to have a result of the proper type.

Upvotes: 3

Views: 221

Answers (2)

log0
log0

Reputation: 10947

What I understand is that you want to parse and evaluate typed arithmetic expression.

The usual strategy (used in compilers) is to build a abstract syntax tree and then evaluate this tree. The pattern you need is http://en.wikipedia.org/wiki/Visitor_pattern.

Basically you represent your program/expression as a tree of Nodes. Node is an abstract class with many derived types that stand for each type of piece of expression. The visitor pattern allow you to call the correct visitor, for each type of node, and thus decide of the correct code to execute.

struct Visitor
{
  void process(IntNode i) { int r = i.getInt(); ... }
  void process(FloatNode f) { float r = f.getFloat(); ... }
};

struct Node
{
    virtual void getProcessed(Visitor v);
};
struct IntNode : Node
{
    virtual void getProcessed(Visitor v) { v.process(*this); }
    int getInt() {...};
};

Upvotes: 2

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275976

Try boost::variant if you have a finite list of possible types.

Suppose you only support int and float. Then your data would be stored as a boost::variant<int,float>.

To access the values, you'd use apply_visitor. Adding two values requires double-dispatch, which is tricky, but doable. Your visitor to one then visits the other argument, and based on the two types generates a different result.

Upvotes: 0

Related Questions