Problem mit QList subclass

Alles rund um die Programmierung mit Qt
Antworten
Ezekeel
Beiträge: 6
Registriert: 2. August 2011 03:33

Problem mit QList subclass

Beitrag 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)]
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Problem mit QList subclass

Beitrag von Christian81 »

Warum leitet man von QList ab? Naja egal. Die compare-Funktion muss natürlich static sein.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Ezekeel
Beiträge: 6
Registriert: 2. August 2011 03:33

Re: Problem mit QList subclass

Beitrag 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?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Problem mit QList subclass

Beitrag 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
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Ezekeel
Beiträge: 6
Registriert: 2. August 2011 03:33

Re: Problem mit QList subclass

Beitrag 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?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Problem mit QList subclass

Beitrag 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...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Problem mit QList subclass

Beitrag 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).
Ezekeel
Beiträge: 6
Registriert: 2. August 2011 03:33

Re: Problem mit QList subclass

Beitrag 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?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: Problem mit QList subclass

Beitrag 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/
Ezekeel
Beiträge: 6
Registriert: 2. August 2011 03:33

Re: Problem mit QList subclass

Beitrag 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.
Ezekeel
Beiträge: 6
Registriert: 2. August 2011 03:33

Re: Problem mit QList subclass

Beitrag 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));
}
Antworten