Hello all,
I have several classes binded by one common interface - say 'sum'
interface which calculates the sum of all the class elements of type
'int'.
class Alphabet
{
int _a;
int _b;
int _c;
char _ch; // some other stray element
friend double sumInterface( int first, ... );
public:
double _sum; // ' double' type introduced to differentiate from above
core elements
Alphabet( void)
{
_a=_b=_c=2;
_sum=sumInterface(_a,_b,_c,-1);
}
};
class Numbers
{
int _one;
int _two;
friend double sumInterface( int first, ... );
public:
double _sum;
Numbers(void)
{
_one=1;
_two=2;
_sum=sumInterface(_one,_two,-1);
}
};
double sumInterface( int first, ... )
{
int i = first;
double sum=0;
va_list marker;
va_start( marker, first ); /* Initialize variable arguments. */
while( i != -1 ) //-1 acts as delimiter
{
sum += i;
i = va_arg( marker, int);
}
va_end( marker ); /* Reset variable arguments. */
return sum ;
}
The problem with this approach is that I need to provide all the class
elements to this function each type I invoke it.
_sum=sumInterface(_a,_b,_c,-1);
_sum=sumInterface(_one,_two,-1);
Is there anyway I make the function to understand to consider all the
class elements of type int so that I dont have to explicitly type all
the elements?
If yes, can I general this concept to other user defined data types?
Also, little off topic but is there a way I can avoid using a delimiter
in the variable length arguments ?
Thank you.
-KK 3 1450
I don't see any way to do this in C++. OTOH, you might be able to use
SWIG to sort of reflect upon your class, generating XML, then generate
the code you need by parsing the XML.
Noel
KK wrote: Hello all, I have several classes binded by one common interface - say 'sum' interface which calculates the sum of all the class elements of type 'int'.
class Alphabet { int _a; int _b; int _c; char _ch; // some other stray element
Why not just add a method:
double evalsum()
{
return sumInterface(_a,_b,_c,-1);
}
To all the classes you care about ?
.... The problem with this approach is that I need to provide all the class elements to this function each type I invoke it.
_sum=sumInterface(_a,_b,_c,-1); _sum=sumInterface(_one,_two,-1);
This would become:
_sum=evalsum(); Is there anyway I make the function to understand to consider all the class elements of type int so that I dont have to explicitly type all the elements?
Not possible with standard C++. If yes, can I general this concept to other user defined data types?
Also, little off topic but is there a way I can avoid using a delimiter in the variable length arguments ?
Use overloaded functions.
double sum( int v1 )
{
return double(v1);
}
double sum( int v1, int v2 )
{
return double(v1) + v2;
}
double sum( int v1, int v2, int v3 )
{
return double(v1) + v2 + v3;
}
....
To as many as you care about
KK wrote: Hello all, I have several classes binded by one common interface - say 'sum' interface which calculates the sum of all the class elements of type 'int'.
class Alphabet { int _a; int _b; int _c; char _ch; // some other stray element friend double sumInterface( int first, ... ); public: double _sum; // ' double' type introduced to differentiate from above core elements Alphabet( void) { _a=_b=_c=2; _sum=sumInterface(_a,_b,_c,-1); } };
class Numbers { int _one; int _two; friend double sumInterface( int first, ... ); public: double _sum; Numbers(void) { _one=1; _two=2; _sum=sumInterface(_one,_two,-1); } };
double sumInterface( int first, ... ) { int i = first; double sum=0; va_list marker; va_start( marker, first ); /* Initialize variable arguments. */ while( i != -1 ) //-1 acts as delimiter { sum += i; i = va_arg( marker, int); } va_end( marker ); /* Reset variable arguments. */ return sum ; }
The problem with this approach is that I need to provide all the class elements to this function each type I invoke it.
_sum=sumInterface(_a,_b,_c,-1); _sum=sumInterface(_one,_two,-1);
Is there anyway I make the function to understand to consider all the class elements of type int so that I dont have to explicitly type all the elements?
No.
If yes, can I general this concept to other user defined data types?
Depending on your design, you may be better with containers. These
classes seem like container-like classes, so you could either
1) typedef them to standard containers
typedef std::vector<int> Alphabet;
typedef std::vector<int> Numbers;
void f(Alphabet &a)
{
int sum = std::accumulate(a.begin(), a.end(), 0);
}
2) use standard containers internally and provide a (standard if
possible) container interface
class Alphabet
{
public:
typedef Cont::iterator iterator;
iterator begin()
{
return cont_.begin();
}
iterator end()
{
return cont_.end();
}
private:
typedef std::vector<int> Cont;
Cont cont_;
};
void f(Alphabet &a)
{
// note: this does not change
int sum = std::accumulate(a.begin(), a.end(), 0);
}
3) Return a container from a member function containing all the values.
That would fit if the class is not really a container. This would wrap
all the values in a container to calculate the sum (or something else)
easily.
class Alphabet
{
public:
typedef std::vector<int> Container;
Container cont() const
{
Container c;
c.push_back(a_);
c.push_back(b_);
return c;
}
private:
int a_, b_;
};
4) Use the sum computed by a member function, which removes the need
for "do-it-all" free function
class Alphabet
{
public:
int sum() const
{
return a_ + b_;
}
private:
int a_, b_;
};
void f(Alphabet &a)
{
int sum = a.sum();
}
You may use inheritance or templates if you need to work with multiple
classes. For example, f() could be rewritten as
template <class C>
int sum(C &c)
{
int sum = std::accumulate(c.begin(), c.end(), 0);
// or
int sum = c.sum();
}
As you see, you are not short of options.
Also, little off topic but is there a way I can avoid using a delimiter in the variable length arguments ?
Yes, don't use variable length arguments.
Jonathan This discussion thread is closed Replies have been disabled for this discussion. Similar topics
50 posts
views
Thread by Dan Perl |
last post: by
|
3 posts
views
Thread by domeceo |
last post: by
|
15 posts
views
Thread by Mon |
last post: by
|
1 post
views
Thread by Augasm |
last post: by
|
6 posts
views
Thread by Adam Hartshorne |
last post: by
|
7 posts
views
Thread by Harolds |
last post: by
|
2 posts
views
Thread by Martin Gernhard |
last post: by
|
17 posts
views
Thread by =?Utf-8?B?U2hhcm9u?= |
last post: by
|
1 post
views
Thread by Ben Warren |
last post: by
| | | | | | | | | | |