Seite 1 von 1

Problem mit QList subclass

Verfasst: 2. August 2011 22:15
von Ezekeel

Code: Alles auswählen

#ifndef LIST_H
#define LIST_H

#include <QList>
#include <QtAlgorithms>

template <typename T>
class List : public QList<T>
{
public:

	inline List() : QList<T>() {}
	inline List(const List<T> &l) : QList<T>(l) {}
	inline List(const QList<T> &l) : QList<T>(l) {}

	bool less_than(int index1, int index2);

	List<int> create_index();

private:
	QList<int> m_index;
};

template <typename T>
bool List<T>::less_than(int index1, int index2) { return (this->at(m_index[index1]) < this->at(m_index[index2])); }

template <typename T>
List<int> List<T>::create_index()
{
	int i;
		
	for (i = 0; i < this->size(); i++)
	{
		m_index << i;
	}

	less_than(0,0);

	qSort(m_index.begin(), m_index.end(), this->less_than);

	List<int> index(m_index);

	m_index.clear();
		
	return index;
};

#endif
Jemand eine Idee, warum das einen compile error auswirft, wenn man bei einem List<T> Objekt die Funktion create_index() aufruft?

Code: Alles auswählen

In file included from music_manager.cpp:6:0:
list.h: In member function ‘List<int> List<T>::create_index() [with T = QString]’:
music_manager.cpp:46:35:   instantiated from here
list.h:60:5: error: no matching function for call to ‘qSort(QList<int>::iterator, QList<int>::iterator, <unresolved overloaded function type>)’
/usr/include/QtCore/qalgorithms.h:209:13: note: candidate is: void qSort(RandomAccessIterator, RandomAccessIterator, LessThan) [with RandomAccessIterator = QList<int>::iterator, LessThan = bool (List<QString>::*)(int, int)]

Re: Problem mit QList subclass

Verfasst: 2. August 2011 22:17
von Christian81
Warum leitet man von QList ab? Naja egal. Die compare-Funktion muss natürlich static sein.

Re: Problem mit QList subclass

Verfasst: 3. August 2011 00:39
von Ezekeel
Naja. Das eigentliche Problem war, daß man eine QList<T> liste zwar sortieren kann, aber keine QList<int> index zur Sortierung erstellen kann, so daß gilt liste[index] < liste[index[i+1]]. Da hat sich eine Subclass von QList angeboten. Wie hättest Du das denn gemacht?

Zu Deinem Vorschlag: Die lessthan Funktion kann ich natürlich nicht static machen, da ich den Zugriff auf die Daten der Liste brauche, da die Funktion ja nicht direkt die Indices, sondern die Daten an Position der Indices vergleicht.

Gibt es keine Möglichkeit eine non-static member function für den Vergleich zu nutzen?

Re: Problem mit QList subclass

Verfasst: 3. August 2011 06:29
von Christian81
Ich verstehe das Problem nicht... was ist jetzt an dem sortieren so falsch? Was willst du so anders sortieren dass es nicht reicht zwei Werte zu vergleichen wie im Beispiel Warum braucht man extra noch eine Indexliste
Eine Funktion deren Pointer ich irgendwo hin übergeben will muss static sein -> C++ Grundlagen

Re: Problem mit QList subclass

Verfasst: 3. August 2011 23:40
von Ezekeel
Christian81 hat geschrieben:Ich verstehe das Problem nicht... was ist jetzt an dem sortieren so falsch? Was willst du so anders sortieren dass es nicht reicht zwei Werte zu vergleichen wie im Beispiel Warum braucht man extra noch eine Indexliste
Ich werde Dir jetzt sicher nicht lang und breit erklären, wofür ich diese Indexliste brauche. Ein einfaches Sortieren reicht halt in meinem Fall nicht, genaue Details sind irrelevant.
Christian81 hat geschrieben:Eine Funktion deren Pointer ich irgendwo hin übergeben will muss static sein -> C++ Grundlagen
Hmm. Diese Beschränkung ist mir noch gar nicht aufgefallen. Mag daran liegen, daß ich OOP normalerweise vermeide wie der Teufel das Weihwasser, weil bei meinen Programmen performance eine Rolle spielt. Ich habe es ausprobiert und das stimmt tatsächlich wohl. Schade. Kennst Du den Grund für diese Beschränkung?

Re: Problem mit QList subclass

Verfasst: 4. August 2011 06:36
von Christian81
Das hat nichts mit C++ zu tun. Wie soll der Compiler einen Pointer zur Compile-Time erzeugen wenn noch nicht einmal klar ist wo das Objekt im Speicher liegt bzw. welches Objekt es ist...

Re: Problem mit QList subclass

Verfasst: 4. August 2011 08:00
von franzf
LessThan ist kein Funktions-Pointer, sondern ein template-Parameter. Daher tuts hier auch ein Funktor.
Entweder du bietest dein less_than direkt über den operator() an, oder du bleibst bei less_than und übergibst an qSort() einen boost::function oder std::tr1::function (via boost::bind oder std::tr1::bind). (wenn du C++-0X verwendest, gibts auch schon std::function/std::bind).

Re: Problem mit QList subclass

Verfasst: 4. August 2011 09:08
von Ezekeel
franzf hat geschrieben:LessThan ist kein Funktions-Pointer, sondern ein template-Parameter. Daher tuts hier auch ein Funktor.
Entweder du bietest dein less_than direkt über den operator() an, oder du bleibst bei less_than und übergibst an qSort() einen boost::function oder std::tr1::function (via boost::bind oder std::tr1::bind). (wenn du C++-0X verwendest, gibts auch schon std::function/std::bind).
Ich denke Du meinst den operator<() oder? Funktor oder boost::function und std::tr1::function sagt mir jetzt gar nichts. Da werde ich mal bisher nach googlen. Ist immer schön was Neues dazu zu lernen.

Das Problem habe ich jetzt erst einmal ganz billig so gelöst

Code: Alles auswählen

template <typename T>
class Index_value
{
public:

    static bool less_than(Index_value & index_value1, Index_value & index_value2);

    int position;

    T value;
};

template <typename T>
bool Index_value<T>::less_than(Index_value & index_value1, Index_value & index_value2)
{
    return (index_value1.value < index_value2.value);
}

template <typename T>
class Indexed_qlist : public QList< Index_value<T> >
{
public:

    inline Indexed_qlist() : QList< Index_value<T> >() { }
};
Dann kann ich Indexed_qlist anstelle von QList verwerden, wenn ich die sortierten Indices brauche. Habe auch probiert statt T nur T* zu speichern, so daß man flexibel auch bereits bestehende QLists benutzen kann ohne die Werte in eine Indexed_qlist umkopieren zu müssen. Dabei bin ich allerdings auf das Problem gestoßen, daß ich keinen Weg gefunden habe an die Adressen der Elemente T* einer QList<T> zu kommen. [] gibt ja nur ein T zurück das eine Kopie des entsprechenden QList-Elementes ist. Gibt es da einen Trick oder kommt man einfach nicht an T* bei einer QList?

Re: Problem mit QList subclass

Verfasst: 4. August 2011 09:12
von franzf
Ich denke Du meinst den operator<() oder?
Nein, ich meine den operator()! Such mal nach Funktor oder Functor.
Schau auch hier, da gibt es ein Beispiel:
http://www.cplusplus.com/reference/algorithm/sort/

Re: Problem mit QList subclass

Verfasst: 5. August 2011 20:47
von Ezekeel
Ich habe mich mal über Funktoren und std::tr1:function informiert und das genau das was ich gesucht habe. Danke Dir, Franz. Ich werde mich heute Abend mal ransetzen und schauen wie ich das jetzt implementiere.

Re: Problem mit QList subclass

Verfasst: 5. August 2011 23:41
von Ezekeel
So. Habs fertig und es funktioniert wie geplant. Danke nochmal für die Hilfe.

Code: Alles auswählen

#include <QList>
#include <QtAlgorithms>
#include <tr1/functional>

template <typename T>
class Index : public QList<int>
{
public:

    Index(QList<T> & qlist);

    bool less_than(int index1, int index2);

private:

    Index();

    QList<T> * m_qlist;
};

template <typename T>
Index<T>::Index(QList<T> & qlist)
: QList<int>()
{
    using namespace std::tr1;
    using namespace std::tr1::placeholders;
	
    int i;
      
    for (i = 0; i < qlist.size(); i++)
	{
	    *this << i;
	}

    m_qlist = &qlist;

    qSort(begin(), end(), bind(mem_fn(&Index<T>::less_than), this, _1, _2));
};

template <typename T>
bool Index<T>::less_than(int index1, int index2)
{
    return (m_qlist->at(index1) < m_qlist->at(index2));
}