
December 2nd, 2005, 01:15 AM
| | | Passing speicifc class elements as arguments without explicitly listing them - is it possible?
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 | 
December 2nd, 2005, 02:35 AM
| | | Re: Passing speicifc class elements as arguments without explicitly listing them - is it possible?
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 | 
December 2nd, 2005, 08:15 AM
| | | Re: Passing speicifc class elements as arguments without explicitlylisting them - is it possible?
KK wrote:[color=blue]
> 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[/color]
Why not just add a method:
double evalsum()
{
return sumInterface(_a,_b,_c,-1);
}
To all the classes you care about ?
....[color=blue]
>
> 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);[/color]
This would become:
_sum=evalsum();
[color=blue]
>
> 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?[/color]
Not possible with standard C++.
[color=blue]
>
> 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 ?[/color]
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 | 
December 2nd, 2005, 08:45 AM
| | | Re: Passing speicifc class elements as arguments without explicitly listing them - is it possible?
KK wrote:[color=blue]
> 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?[/color]
No.
[color=blue]
> If yes, can I general this concept to other user defined data types?[/color]
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.
[color=blue]
> Also, little off topic but is there a way I can avoid using a delimiter
> in the variable length arguments ?[/color]
Yes, don't use variable length arguments.
Jonathan |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over network members.
|