Awkward reference argument in Array::indexOfSorted


#1

Given:

  SliderHandler* handler = m_sliderHandlers.indexOfSorted (
    Handler::Compare (), slider);

This warning is generated (MSVC):

1>d:\projects\layereffects\layereffects\source\gui\coptionstab.cpp(67): warning C4239: nonstandard extension used : 'argument' : conversion from 'COptionsTab::Handler::Compare' to 'COptionsTab::Handler::Compare &'
1>          A non-const reference may only be bound to an lvalue

Because the ElementComparator parameter is a non const reference:

    template <typename ElementComparator, typename TargetValueType>
    int indexOfSorted (ElementComparator& comparator, TargetValueType elementToLookFor) const

Since we’re dealing with a template function I think it would be okay to simply pass ElementComparator by value (?)


#2

Hmm, I think that’d break any code that uses a non-copyable sorter class…


#3

I’m trying to set up a simple array that associates each Component with a “handler” object. So when I get a listener notification I want to look up the control in the array. This is what I have:

void COptionsTab::sliderValueChanged (Slider* slider)
{
  Handler::Compare comparison;
  int index = m_sliderHandlers.indexOfSorted (comparison, slider);
  jassert (index != -1);
  SliderHandler* handler = m_sliderHandlers [index];
}

This doesn’t even work, the call to indexOfSorted() wont compile because the array and comparison routines are declared this way:

  struct Handler : vf::Uncopyable  {
    struct Compare {
      static int compareElements (Handler* lhs, Handler* rhs) { return rhs - lhs; }
      static int compareElements (Handler* lhs, Component* rhs) { return rhs - lhs->getComponent (); }
    };
    explicit Handler (Component* component);
    Component* getComponent () const;
  private:
    Component* const m_component;
  };

and

Array <SliderHandler*> m_sliderHandlers;

juce::Array is an improvement over std::vector for many things especially when you dont want copy by value. But the interface and behavior of sorted Array and OwnedArray in JUCE is lacking. It is awkward to search in a sorted array with something other than the base object type.

It would be great if it was easy to maintain the sorted array and search for any key without requiring local variables or all kinds of weirdness.


#4

Just a C++ note on this - generally, your comparators and sorters should always be copiable/passed by value.

There’s little or no advantage in using non-copiable functors (you can always pass in a pointer to your actual non-copiable class into your functor’s constructor if it comes down to that), almost all frameworks including STL assume that your comparator functors are copiable, and there are significant advantages (as El Vinn has pointed out).


#5

Let’s change it and see if anyone complains?


#6

I hope you don’t practice medicine in your spare time. :wink: