Reputation: 65
I have a class with "array of array" private member represented as:
std::deque<std::deque<SomeClass> > someArray_;
Also this class have a public method which allows to receive all unique SomeClass
instances, containing in someArray_
. Unique for SomeClass
instances means different by at least one of several class members. I decided to use std::set
for that purpose. This method has prototype like following:
std::set<SomeClass> getAllUniqueInstances() const;
In this method implementation I use following construction to populate std::set
:
std::set<SomeClass> allUniqueInstances;
for(auto it = std::begin(someArray_); it != std::end(someArray_); ++it){
std::copy((*it).begin(),
(*it).end(),
std::inserter(allUniqueInstances, allUniqueInstances.end()));
}
operator<()
is defined for SomeClass
class. As a result my std::set
is populated, but huge amount of instances is missed. Modyfing operator<()
for SomeClass
class, alters situation, but breaks desirable sorting order. How in this case std::copy
determines whether considerable instance is unique?
UPD: source code for SomeClass
class SomeClass{
private:
uint32_t from_;
uint32_t to_;
double capacity_;
double flow_;
public:
...
bool operator<(const SomeClass& rhs) const;
...
};
I want SomeClass
instances to be ordered in set by from_
member:
bool SomeClass::operator<( const SomeClass& rhs ) const{
if(this->from_ < rhs.from_)
return true;
return false;
}
Upvotes: 2
Views: 1692
Reputation: 227468
It is not std::copy
who decides whether instances are unique, but std::set
. The logic is something like
(A < B is false) and (B < A is false)
So the criterion that defines the ordering also defines the "uniqueness". It seems like std::set
is the wrong data structure for this problem, or your ordering criteria are either incorrect (as in not implementing strict weak ordering), or too broad to suit the problem (as in, you order based on a small number of attributes when you could use more).
Here is an example of a lexicographical comparison using more attributes than you currently have:
#include <tuple> // for std::tie
bool SomeClass::operator<( const SomeClass& rhs ) const
{
return std::tie(from_, to_, capacity_, flow_) < std::tie(rhs.from_, rhs.to_, rhs.capacity_, rhs.flow_);
}
Upvotes: 5