subset of a POD

H

Hicham Mouline

Hello,

I have functions that each take 1 parameter. This parameter is of type

struct S {
<arithmetic_or_bool_type_1> member_name_1;
<arithmetic_or_bool_type_n> member_name_n;
}; // n can be of order 10 or so

class C {
public:
return_type apply( const S& ) const;
};

Now I want to optimize the returned value.

I would optimize by fixing any subset of the n members fixed, ie none at
all, or just member 5, or members 4 and 8, or members 7,3 and n, or n-1
members of the {1....n} set.

How can I do this?

maybe

class C{
public:
pair<return_type, S> optimize(...) const; // returns the optimum S
that gives the best return value
};

Some interface like this looks nice to me (as a user).

The question is how to pass the fixed members to optimize.

regards,
 
V

Victor Bazarov

Hicham said:
I have functions that each take 1 parameter. This parameter is of type

struct S {
<arithmetic_or_bool_type_1> member_name_1;
<arithmetic_or_bool_type_n> member_name_n;
}; // n can be of order 10 or so

class C {
public:
return_type apply( const S& ) const;
};

Now I want to optimize the returned value.
"Optimize"?

I would optimize by fixing any subset of the n members fixed, ie none at
all, or just member 5, or members 4 and 8, or members 7,3 and n, or n-1
members of the {1....n} set.

How can I do this?

If your 'return_type' has to be the same *type*, there is no better
solution than to return an 'S', if the members that you don't want to
"return" are set to some "invalid" value. As an alternative you could
consider supplying another member to 'S', which would indicate the
"valid" or "active" members. You can have another (nested) struct in
'S' with bit fields:

struct S {
... // as you have now
struct {
unsigned use_1:1;
unsigned use_2:1;
...
unsigned use_n:1;
} which_members_to_use;
};
maybe

class C{
public:
pair<return_type, S> optimize(...) const; // returns the optimum S
that gives the best return value

What's "return_type" here? What does it mean for the return value to be
"the best"?
};

Some interface like this looks nice to me (as a user).

The question is how to pass the fixed members to optimize.

It is unclear what solution would be better since you've not explained
what problem you're trying to solve with this mechanism.

V
 
V

Vladimir Jovic

Victor said:
If your 'return_type' has to be the same *type*, there is no better
solution than to return an 'S', if the members that you don't want to

Maybe returning "const S&" would be better?
"return" are set to some "invalid" value. As an alternative you could
consider supplying another member to 'S', which would indicate the
"valid" or "active" members. You can have another (nested) struct in
'S' with bit fields:

struct S {
... // as you have now
struct {
unsigned use_1:1;
unsigned use_2:1;
...
unsigned use_n:1;
} which_members_to_use;
};

Using "bool use_1" might be clearer then "unsigned use_1:1".
 
V

Vladimir Jovic

Victor said:
And what would it refer to?

You should know the answer :p
A static variable, or a class member holding the result.
Clearer, maybe. More expensive, for sure.

So, next two structures are not the same?
struct A
{
bool use1;
bool use2;
//... more bool
bool use32;
}

struct B
{
unsigned use1:1;
unsigned use2:1;
//... more unsigned:1;
unsigned use32:1;
}

Or, is bool expanded to 8 bits, or something different then 1 bit in
this case?
 
J

James Kanze

Victor Bazarov wrote:

[...]
So, next two structures are not the same?
struct A
{
bool use1;
bool use2;
//... more bool
bool use32;
}
struct B
{
unsigned use1:1;
unsigned use2:1;
//... more unsigned:1;
unsigned use32:1;
}
Or, is bool expanded to 8 bits, or something different then 1
bit in this case?

bool must be addressable; you can have bool*, and in the first
struct, you can take the address of each of the bool's. And
sizeof(bool) must be an integral value. This imposes a minimum
size equal to that of char. (The actual size is implementation
defined, and it wouldn't surprise me if there were
implementations where bool was the same size as an int.)

A variable declared as a bit field doesn't have an address,
i.e.:

A* pa;
B* pb;
bool* b1 = &pa->use1; // legal...
bool* b2 = &pb->use1; // illegal...
 
V

Vladimir Jovic

James said:
bool must be addressable; you can have bool*, and in the first
struct, you can take the address of each of the bool's. And
sizeof(bool) must be an integral value. This imposes a minimum
size equal to that of char. (The actual size is implementation
defined, and it wouldn't surprise me if there were
implementations where bool was the same size as an int.)

Great. Thanks for the explanation. Who would have thought of that ;)
 
H

Hicham Mouline

Victor Bazarov said:
If your 'return_type' has to be the same *type*, there is no better
solution than to return an 'S', if the members that you don't want to
"return" are set to some "invalid" value. As an alternative you could
consider supplying another member to 'S', which would indicate the "valid"
or "active" members. You can have another (nested) struct in 'S' with bit
fields:

struct S {
... // as you have now
struct {
unsigned use_1:1;
unsigned use_2:1;
...
unsigned use_n:1;
} which_members_to_use;
};


What's "return_type" here? What does it mean for the return value to be
"the best"?


It is unclear what solution would be better since you've not explained
what problem you're trying to solve with this mechanism.

V
I apologize for being unclear.

return_type is just double.

C c;
S s1;
c.apply( s1 ); //// returns double , say 15.0

By optimize, I mean in most cases maximize, but sometimes minimize.
So I'm trying to get the largest double by changing parts or all of s1.

I was thinking of some metaprogramming magic that would generate
automatically S constructors with arguments all the possible subsets of the
member fields, and depending on the ctor selected by the user, would set
those bits or bools in the nested struct appropriately. This could generate
also getters/setters that the optimize function could use .
This could be a metafunction that returns a type SS based on the type S.
I realize this is definitely a question for boost as well.

The C::eek:ptimize function would then return the "optimal" S, along with the
maximum double found.
The details and meaning of the optimization would be specific to
C::eek:ptimize.

Best regards,
 
V

Victor Bazarov

James said:
Vladimir said:
Victor Bazarov wrote:
Hicham Mouline wrote:
[...]
"return" are set to some "invalid" value. As an alternative you could
consider supplying another member to 'S', which would indicate the
"valid" or "active" members. You can have another (nested) struct in
'S' with bit fields:
struct S {
... // as you have now
struct {
unsigned use_1:1;
unsigned use_2:1;
...
unsigned use_n:1;
} which_members_to_use;
};
Using "bool use_1" might be clearer then "unsigned use_1:1".
Clearer, maybe. More expensive, for sure.

More expensive in memory. Probably significantly less expensive
in runtime.

Curious, isn't it, how one can easily tell when it's more expensive from
the memory standpoint, and how unknown the expense in terms of the run
time is. We can't tell whether it's "significantly less expensive"
until we actually measure, can we? <g>

V
 
J

James Kanze

James said:
Vladimir Jovic wrote:
Victor Bazarov wrote:
Hicham Mouline wrote:
[...]
"return" are set to some "invalid" value. As an
alternative you could consider supplying another member
to 'S', which would indicate the "valid" or "active"
members. You can have another (nested) struct in 'S'
with bit fields:
struct S {
... // as you have now
struct {
unsigned use_1:1;
unsigned use_2:1;
...
unsigned use_n:1;
} which_members_to_use;
};
Using "bool use_1" might be clearer then "unsigned use_1:1".
Clearer, maybe. More expensive, for sure.
More expensive in memory. Probably significantly less expensive
in runtime.
Curious, isn't it, how one can easily tell when it's more
expensive from the memory standpoint, and how unknown the
expense in terms of the run time is. We can't tell whether
it's "significantly less expensive" until we actually measure,
can we? <g>

Technically no, and the "more expensive" also depends on what
you're doing with the object. Which is why I said
"probably":). Still, none of the machines I know can
physically access less than a byte at a time, so runtime access
to the bit fields requires additional masking and possibly
shifting, and modifying them requires a read before hand in
order to avoid modifying neighboring bitfields.

The next version of the standard will recognize this, at least
partially---accessing different bitfields in a single struct is
considered accessing a single object with regards to threading,
i.e.:

struct S1 { bool b1 ; bool b2 ; } s1;
struct S2 { bool b1:1; bool b2:1; } s2;

Given the above, one thread can use s1.b1, and another s1.b2,
without any external synchronization; the same scenario for s2
is undefined behavior.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top