Inheritance, templates, nothing solves my problem!?

R

RThaden

Hi all,

I looked in several books, articles, etc. but did not find a solution
to my problem. Maybe somebody out there can help a desperate, not toooo
experienced programmer:

I want to represent functional blocks by lists of parameters.
Lets say, functional blocks represent different algorithms which, of
course, have very different parameters.
Thus, a functional block contains lists of parameters which, and now
comes the problem, can be of different types. It is not known at
compile time, how many parameters and which types.
The parameters are characterized by their name.

A parameter should be an object like this

set/getValue()
set/get/MaxMin()
string set/getName()

The value can be of type int or double (and maybe, who knows, in the
future there will be other types).
Thus, it is not possible to do it via an abstract base class
abstractParam and inheritance since the inherited classes would differ
in type (and which type should I supply to the abstract base class).

Sounds like templates would be a solution but, then, how should I
maintain a list of parameters in a functional block?

Parameter:
template <class T> param:

FunctionalBlock ... {
list<param> params;
....
}

does not work since the list expects specialized values, thus, params
must carry type information.

I could just put two lists in a functional block, one with int
parameters and one with double parameters.
Disadvantages: I have to iterate over two lists which is not that bad,
but if in the future a third type will be added, I have to modify all
the code dealing with this.

Any ideas for a solution?

Thanks in advance,

Rainer
 
O

Ondra Holub

(e-mail address removed) napsal:
Hi all,

I looked in several books, articles, etc. but did not find a solution
to my problem. Maybe somebody out there can help a desperate, not toooo
experienced programmer:

I want to represent functional blocks by lists of parameters.
Lets say, functional blocks represent different algorithms which, of
course, have very different parameters.
Thus, a functional block contains lists of parameters which, and now
comes the problem, can be of different types. It is not known at
compile time, how many parameters and which types.
The parameters are characterized by their name.

A parameter should be an object like this

set/getValue()
set/get/MaxMin()
string set/getName()

The value can be of type int or double (and maybe, who knows, in the
future there will be other types).
Thus, it is not possible to do it via an abstract base class
abstractParam and inheritance since the inherited classes would differ
in type (and which type should I supply to the abstract base class).

Sounds like templates would be a solution but, then, how should I
maintain a list of parameters in a functional block?

Parameter:
template <class T> param:

FunctionalBlock ... {
list<param> params;
...
}

does not work since the list expects specialized values, thus, params
must carry type information.

I could just put two lists in a functional block, one with int
parameters and one with double parameters.
Disadvantages: I have to iterate over two lists which is not that bad,
but if in the future a third type will be added, I have to modify all
the code dealing with this.

Any ideas for a solution?

Thanks in advance,

Rainer

Hi Rainer.

I would store one parameter in some variant class (let's say
Parameter), which knows the type of parameter (int, double, etc.). If
you define for such class copy constructor and assignment operator, you
can easily store instances of Parameter in std::map<std::string,
Parameter>. values in this map are indexed with std::string, so it is
name of parameter and there is simple to find them.

Ondra
 
R

RThaden

Ondra said:
(e-mail address removed) napsal:

Hi Rainer.

I would store one parameter in some variant class (let's say
Parameter), which knows the type of parameter (int, double, etc.). If
you define for such class copy constructor and assignment operator, you
can easily store instances of Parameter in std::map<std::string,
Parameter>. values in this map are indexed with std::string, so it is
name of parameter and there is simple to find them.

Hi Ondra,

never heard of a variant class, so after googling for it, I was
referred to the boos library and it seems, this library provides what I
need.

Another approach would be to construct only one type holding a double
and cast it down to int if needed. The strings are anyway read from a
table so this could also be done by doubles casted to int.
I wonder, how costly this boost::variant is. Do you have an idea?
 
O

Ondra Holub

Hi Ondra,
never heard of a variant class, so after googling for it, I was
referred to the boos library and it seems, this library provides what I
need.

Another approach would be to construct only one type holding a double
and cast it down to int if needed. The strings are anyway read from a
table so this could also be done by doubles casted to int.
I wonder, how costly this boost::variant is. Do you have an idea?

Hi Rainer.

I have never used boost::variant, but all boost classes are written
very well. Most of them will be part of next C++ standard.

With variant class I meant some class, which is able to store more than
1 type. It is not problem, there may be stored as many attributes as
memory allows. There must be also some mechanism how to check, which
type is currently stored inside. Something like this:

class Parameter
{
public:
typedef
enum { INT, DOUBLE } Type;

Parameter(int data)
: type_(INT),
idata_(data)
{
}

Parameter(double data)
: type_(DOUBLE),
ddata_(data)
{
}

Parameter(const Parameter& src)
: type_(src.type_),
idata_(src.idata_),
ddata_(src.ddata_)
{
}

Parameter& operator=(const Parameter& src)
{
type_ = src.type_;
idata_ = src.idata_;
ddata_ = src.ddata_;

return *this;
}

Type GetType() const { return type_; }

void SetData(int data)
{
type_ = INT;
idata_ = data;
}

void SetData(double data)
{
type_ = DOUBLE;
ddata_ = data;
}

int GetIntData() const { assert(type_ == INT); return idata_; }
double GetDoubleData() const { assert(type_ == DOUBLE); return
ddata_; }

private:
Type type_;
int idata_;
double ddata_;
};

Solution in boost is more generic, my solution is simpler but harder to
maintain in case of need to add more types.

Ondra
 
M

mlimber

Ondra said:
I have never used boost::variant, but all boost classes are written
very well. Most of them will be part of next C++ standard.

No, a *few* of them will *likely* be part of the next C++ standard
library.

Cheers! --M
 

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
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top