typedef struct {
int a;
int b;
int c;
int d;
} IntStruct;
now i wanted to write a Getter and setter for this struct members.
IntStruct obj;
obj.Get(i) // Returns me the members at ith
position.
obj.Set(i) // Set ith member of struct....
If all the members of same data types... and another is can i do some
thing else if data members of different type.
can i use any operator overloading for accessing these members.
Thanks in advance
K2G
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
{ Edits: quoted signature & clc++m banner removed. Since the banner is
automatically appended to every article there's no need to quote it. -mod }
Surely language isn't designed to accomplish this ! I guess most of
the systems might not need this approach as the maintenance of the
code is going to be tough !
- Bharath
http://www.boost.org/doc/libs/1_35_0/libs/tuple/doc/tuple_users_guide.html
The *almost* qualifier is because N in the:
get<N>(t)
expression for tuple t must be a compile time constant. Is that close
enough?
> Hi,
> I wanted to extract all the members based on the index of struct.
> for example
>
> typedef struct {
> int a;
> int b;
> int c;
> int d;
> } IntStruct;
>
> now i wanted to write a Getter and setter for this struct members.
>
>
> IntStruct obj;
> obj.Get(i) // Returns me the members at ith
> position.
> obj.Set(i) // Set ith member of struct....
>
> If all the members of same data types... and another is can i do some
> thing else if data members of different type.
> can i use any operator overloading for accessing these members.
>
> Thanks in advance
> K2G
int get(intStruct &a,int i)
{
switch(i)
{
case 0: return a->a;
case 1: return a->b;
case 2: return a->c;
case 3: return a->d;
defualt:
// out of range handle this
}
}
if the struct contains different types a boost::variant can be used
see also boost::fusion since it can adapt a struct as a fusion sequence
and then it becomes a problem of converting the runtime index into
a function call with a compile_time_index via a switch or equivalent.
Not sure whether it is really worth it:) since you can always just
do something like the above directly but it can become a maintaince
nightmare....
I've made a small generic utility, named "record", that does what you
want : a tuple with a dynamic access to its elements.
http://www.codeproject.com/KB/cpp/record.aspx
Alexandre Courpron.
typedef struct {
int a;
int b;
int c;
int d;
} IntStructHelper;
typedef struct {
union
{
int arr_[1];
IntStructHelper ih_;
};
int operator[](int i) { return arr_[i]; }
} IntStruct;
int main()
{
IntStruct is;
int b = is[1]; // refers to is.ih_.b;
My brief look at record.aspx reminded me, a little, of the
recently proposed boost switch_:
http://dancinghacker.com/switch/boost_switch/switch_.html
Could you highlight the differences between your record
and the proposed boost switch_. The above .html is probably
old by now; however, the boost review result was announced here:
http://lists.boost.org/Archives/boost/2008/01/132489.php
and that might provide you with more information.
Hi Larry,
A "record" is basically a tuple with a switch to enable dynamic
access. From what I've seen : "boost::switch_" is a generic utility to
generate switch statements. Therefore, I can only highlight the
differences between boost::switch_ and the dynamic part of a "record"
which is implemented by a switch. I will talk only about performances
related differences.
At first sight, both implementations are based on the same rationale :
using a template wrapper structure and specializing it with the number
of cases.
There is mainly 2 differences :
1) The record's switch doesn't need a default case and uses compiler's
specific keywords to tell the compiler that the default case is
unreachable. The "is_valid_index" can be called to test whether the
"index" provided to the switch is valid or not. For the record
implementation, this is a fast and convenient way[1] to proceed
because is_valid_index is just a comparison to the max bound. However,
this can't be done in the context of a generic switch such as
boost::switch_.
2) "record" has an alternative implementation of its switch statement
that takes internally, as a parameter, the address of the concerned
element instead of the whole collection. This has some advantages and
drawbacks. See the subsection "Branch elimination" of my article.
Those are first impressions. I haven't checked thoroughly the current
boost::switch_ implementation.
Alexandre Courpron.
[1] : we could use the default case here to set an out-of-bounds
handler given by the user, since the compiler jumps to the default
case after making internally the same check as is_valid_index. For
compilers that don't have a specific keyword to remove this check,
using an "is_valid_index" function before the switch leads to 2 checks
(1 by is_valid_index and 1 by the switch) when the index is valid. In
reality, because of branch prediction, that won't lead to a
performance degradation. On the other hand, using an "is_valid_index"
function removes the out-of-bounds handling code from the default case
and ultimately from the switch :
if ( is_valid_index(x) )
apply_switch(x,functor ...) ;
else
out_of_bounds handler ;
This makes the switch lighter and easier to inline.
If they're all the members have a common same type, you could just use
an array of pointers-to-member.
Otherwise, you'll need metafunctions to obtain their type from the
index. Like boost::mpl::vector_c.
- Marsh