I have a set of types which looks like this:
struct MyFlag
{
SomeId source_id; // INVALID_ID by default
SomeData data; // regular type
friend bool operator==( const MyFlag& a, const MyFlag& b ) { return a.source_id == b.source_id; }
friend bool operator<( const MyFlag& a, const MyFlag& b ) { return a.source_id < b.source_id; }
friend bool operator!=( const MyFlag& a, const MyFlag& b ) { return !(a == b); }
friend bool operator==( const SomeId& a, const MyFlag& b ) { return a == b.source_id; }
friend bool operator<( const SomeId& a, const MyFlag& b ) { return a < b.source_id; }
};
MyFlag flag_a { id, data_A };
MyFlag flag_b { id, data_B };
assert( flag_a == flag_b );
assert( flag_a.data != flag_b.data );
assert( flag_a == id );
assert( flag_b == id );
MyFlag flag = flag_b;
assert( flag == flag_a );
assert( flag == id );
assert( flag.data != flag_a.data );
const MyFlag flag_x ={ id_x, data_A };
flag = flag_X;
assert( flag != flag_a );
assert( flag.data == flag_a.data );
That is, only a specific part of the state of the object is considered in comparison: in this example, any MyFlag object would be compared to others using their ids, but not the rest of the data they contain.
I think it match the definition Sean Parent gave of a "value type", but I also think this is a strange or unfamiliar (but useful in my case) pattern.
So my question is: is there a concept name for this ... concept?
How is that kind of type useful? I use this kind of type in a "black board" event system which is basically a kind of set of any value that have a type that is at least regular. However, this black board systematically overwrite the value pushed (inserted) in it even if it's already found (through comparison). That way, I overwrite the full state of a value in the black board using the comparison operators as identifiers.
I have no idea if it's a well known pattern or idea or if it's problematic on the long run. So far it have been very useful. It also feels like something that might be "too smart", but I lack experience with this pattern to confirm that. It might be that I am abusing the use of comparison operators, but it feels that the semantic of these types is correct in my use.
I can provide a detailed example of my usage if necessary.
The type has correct comparison operators defining a total ordering and is therefore
TotallyOrdered(using the N3351 definition).That does not distinguish whether the total ordering compares all of the object state or not, but there does not seem to be any concept for differentiating that. Because it would neither be possible to define (the
==says the objects are equal based on the compared part of the state, how can you tell whether there is also any uncompared part?) nor does any algorithm reason to care.