tags:

views:

157

answers:

1

I have an std::set with the Compare class which requires additional parameter to compare keys. This variable parameter is determined in run-time and I pack it inside the set's keys just to make it accessible to Compare.

However, the parameter logically belongs to the set rather than the keys so this solution looks awkward and duplicates the same value over all keys.

Is there an elegant way to pass additional parameter to the Compare class? (I first thought about set::value_comp, but it returns compare object by value while I need a reference).

Thanks.

+1  A: 

The definition of std::set is:

template <
      class Key, 
       class Traits=less<Key>, 
       class Allocator=allocator<Key> 
>
class set

So Traits is should be your compare operator, but if would look at constructor, you can see it there again:

explicit set(
   const Traits& _Comp
);

So just pass your instance to constructor. (Note it is done by copying)

Dewfy
This answer is correct but I found it hard to follow. To clarify: you need to create a comparison object with the additional parameters inside, then pass that object to the std::set constructor. Don't try to modify the parameters after the set is constructed.
Mark Ransom
@Mark Ransom - there is nos silver bullet, if rule of sorting is changed, then entire set must be rebuilt. If parameters doesn't affect sorting order then you can pass it to Traits by reference or pointer.
Dewfy
There's no way to rebuild a set, other than copying it to a new one, so I stand by my statement. The comparison object must always return the same value when given the same set of inputs, otherwise the set may malfunction.
Mark Ransom
@Mark Ransom - yes, you cannot rebuild set, only over copying. Well, always there are two ways: can you separate your comparison rule onto 2 parts: (1) unmutable (2) depending on parameters. Than you can rebuild (by erasing and temporary copying to another set) only part of set in range returned by applying std::set::equal_range (rule 1). After you can use special set::insert - for sorting order. As result you get O(ln(n)) complexity.
Dewfy
Jack