Probem trying to use STL priority_queue


#1

I created the following definition

typedef
std::priority_queue juce::MidiMessage
MidiEventPriorityQueue;

and then in another class, I declared an instance variable of type MidiEventPriorityQueue.

Compilation was fine but linking failed with the error message below. My rusty C++ indicates that the problem is probably that the compiler couldn’t decide which of the existing operator< implementations to use but for the life of me I can’t remember how to (or even if it is possible to) force any of them to be used (the one with the Time type would probably be fine).

I’m not sure why it didn’t just use the operator< defined for MidiMessage itself.

Is it the case that my only alternative is to include a Compare ‘type’ in the priority_queue template and do it myself?

Thanks,
David

/usr/include/c++/4.2.1/bits/stl_function.h:227:0 /usr/include/c++/4.2.1/bits/stl_function.h:227: error: no match for ‘operator<’ in ‘__x < __y’

note: candidates are:
bool juce::operator<(const juce::Time&, const juce::Time&)
bool juce::operator<(const juce::RelativeTime&, const juce::RelativeTime&)
bool juce::operator<(const juce::String&, const juce::String&)


#2

There’s no “<” operator defined for MidiMessage , that’s why.

You can define one yourself, for example :

bool operator<(const juce::MidiMessage& mm1,const juce::MidiMessage& mm2) { return mm1.getTimeStamp () <mm2.getTimeStamp () ; }

That’s if you want to use the message timestamp as a sorting criterion. I don’t know if it makes sense in the ontext of your application though. HTH


#3

Thanks for responding. I am sorry but I should have mentioned that I had tried creating precisely that boolean operator in the header file (esssentially exactly as you wrote it) but the compiler doesn’t seem to want to pick it up.

My complete header file was

#ifndef __MidiEventPriorityQueue__
#define __MidiEventPriorityQueue__

#include "juce.h"
#include <queue>

typedef
   std::priority_queue <juce::MidiMessage>
      MidiEventPriorityQueue;

bool operator< (const juce::MidiMessage & left, const juce::MidiMessage & right)
{
   return false; // I didn't actually care what's in here, just trying to get the compiler to pick up this definition
}

#endif

#4

You might need to wrap your function in the juce namespace, so the compiler can use Koenig lookup to find it.


#5

Actually, I had tried that too but then at link time I got told I had duplicate symbols, so I assume there was already a juce::operator< defined somewhere (but I don’t know why that wasn’t seen by the compiler)


#6

OK my entire team is completely baffled by this one. We’re unable to get past this issue.

I wonder if someone else could try to reproduce this issue, it’s very bizarre. Just throw the code below into a new class, include it in another class and then create an instance variable of type MidiEventPriorityQueue and see if it can be built. We’re doing this on a Mac with xcode so I’m not sure if there’s something funky with that environment. I don’t understand why the operator< defined directly below is not being picked up by the compiler.

[code]
#ifndef MidiEventPriorityQueue
#define MidiEventPriorityQueue

#include “juce.h”
#include

typedef
std::priority_queue juce::MidiMessage
MidiEventPriorityQueue;

bool operator< (const juce::MidiMessage & left, const juce::MidiMessage & right)
{
return false; // I didn’t actually care what’s in here, just trying to get the compiler to pick up this definition
}

#endif[/code]


#7

I just figured it out … your Koenig lookup suggestion was dead on. However, I was mislead by your suggestion to wrap the function in juce namespace. When I did that, it all compiled but I got link errors about duplicate symbols and got completely sidetracked looking for an existing definition of operator< for MidiMessage.

Turns out (sigh) the problem was that I defined operator< in a header file (I was being lazy) and it got picked up twice in the implementation C++ file (although I’m not sure why, the header was wrapped with the appropriate #ifndef stuff).

When I moved the implementation of operator< to its own CPP file, the duplicate symbol problem went away and all is well.

These exercises are helping to remind me why I stopped using C++ so many years ago. Jules, why couldn’t you have done juce in Pascal? :cry:

I hope this helps someone else.


#8

Oh, C++ isn’t so bad! I only found it difficult for the first 15 years or so… :wink: