[gelöst] conversation vector<string> zu QStringList
-
QtBerserker
- Beiträge: 71
- Registriert: 15. Mai 2006 09:07
[gelöst] conversation vector<string> zu QStringList
Hi,
gibt es einen (einfachen) Weg zur Konversation von vector<string> zu QStringList und umgekehrt? Meine bisherigen Versuche endeten einfach zu kompliziert.
Grüße
Olaf
gibt es einen (einfachen) Weg zur Konversation von vector<string> zu QStringList und umgekehrt? Meine bisherigen Versuche endeten einfach zu kompliziert.
Grüße
Olaf
Zuletzt geändert von QtBerserker am 14. November 2006 19:15, insgesamt 1-mal geändert.
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
-
QtBerserker
- Beiträge: 71
- Registriert: 15. Mai 2006 09:07
Ok, in Analogie zur STL:Christian81 hat geschrieben:Mir ist da auch keine Funktion bekannt - musst wohl oder übel über alle Items iterieren und mit QString::fromStdString() konvertieren...
Code: Alles auswählen
namespace Qt {
typedef std::vector<std::string>::iterator input_iterator;
typedef QList<QString>::iterator output_iterator;
output_iterator copy(input_iterator from_first, input_iterator from_last, output_iterator to_first)
{
while (from_first != from_last) {
to_first->fromStdString(*from_first);
++from_first;
++to_first;
}
return to_first;
}
}
return braucht man nicht, also:
Code: Alles auswählen
namespace Qt {
typedef std::vector<std::string>::iterator input_iterator;
typedef QList<QString>::iterator output_iterator;
void copy(input_iterator from_first, input_iterator from_last, output_iterator to_first, output_iterator to_last)
{
while (from_first != from_last && to_first != to_last) {
to_first->fromStdString(*from_first);
++from_first;
++to_first;
}
}
}
std::vector<std::string> v1;
QStringList v2;
copy(v1.begin(), v1.end(), v2.begin(), v2.end());
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Ich verstehe nicht was v2.begin(), v2.end() soll - da muss doch somit davor erst die QStringList gross genug gemacht werden...
Was ist gegen
einzuwenden?
Was ist gegen
Code: Alles auswählen
v2 += QString::fromStdStringQString::fromStdString(*from_first);
MfG Christian
'Funktioniert nicht' ist keine Fehlerbeschreibung
'Funktioniert nicht' ist keine Fehlerbeschreibung
Die Vektoren mussen sowieso gleich groß sein, sonst funktioniert die while-schleife in dieser Implementierung nicht. ..Christian81 hat geschrieben:Ich verstehe nicht was v2.begin(), v2.end() soll - da muss doch somit davor erst die QStringList gross genug gemacht werden...
Was ist gegeneinzuwenden?Code: Alles auswählen
v2 += QString::fromStdStringQString::fromStdString(*from_first);
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
nun ja, die engültige konvertierung würde in dem hier beschriebenen Fall dann so aussehen:
die copy() funktion müsste man dann auch anpassen, so dass sie nicht nur mit std::vector::iterator arbeiten kann, sondern den iteratortyp als template argument bekommt...
dann hätte man eine universelle Konvertierung von einem std::string-Kontainer zu QStringList.
Was Du vorschlägst funktioniert natürlich auch...
Code: Alles auswählen
template <typename InIt>
QStrlingList convertFromStdStringContainer(InIt begIt, InIt endIt){
QStringList output;
output.resize(endIt-begIt);
copy(begIt, endIt, output.begin(), output.end());
return output;
}
dann hätte man eine universelle Konvertierung von einem std::string-Kontainer zu QStringList.
Was Du vorschlägst funktioniert natürlich auch...
-
QtBerserker
- Beiträge: 71
- Registriert: 15. Mai 2006 09:07
gut, die erste Lösung war etwas holprig, wie Euch bereits aufgefallen ist, muss der QListVector erst'mal resized werden.
Hier eine neue Lösung, die auch den assert Test (stdsv.size() == qtsl.size()) bestand:
using:
Diese Lösung funzt zumindest für den g++ 4.1.2, wobei die zweite Spezialisierung mit dem g++ nicht notwendig ist, evtl. aber bei VC notwendig wird. Prinzipiell kann man somit auch andere Qt Sachen spezialisieren. So, nun macht mich fertig 
Olaf
Hier eine neue Lösung, die auch den assert Test (stdsv.size() == qtsl.size()) bestand:
Code: Alles auswählen
namespace std {
template<>
class back_insert_iterator<QStringList> : public iterator<output_iterator_tag, void, void, void, void>
{
protected:
QStringList* container;
public:
typedef QStringList qcontainer_type;
typedef std::vector<std::string> scontainer_type;
explicit back_insert_iterator(qcontainer_type& x)
: container(&x)
{ }
back_insert_iterator& operator=(scontainer_type::const_reference value) {
container->push_back(QString().fromStdString(value));
return *this;
}
back_insert_iterator& operator*() { return *this; }
back_insert_iterator& operator++() { return *this; }
back_insert_iterator operator++(int) { return *this; }
};
template<>
inline back_insert_iterator<QStringList>
back_inserter(QStringList& x) { return back_insert_iterator<QStringList>(x); }
}
Code: Alles auswählen
std::copy(first, last,std::back_inserter(qtstrlst));
Olaf
Nun ja, das wäre eine STL-konforme Lösung... Die lässt sich aber für alle Kontainertypen verallgemeinern:
using:
Code: Alles auswählen
namespace std {
template<typename InputContainerType>
class back_insert_iterator: public iterator<output_iterator_tag, void, void, void, void>
{
protected:
QStringList* container;
public:
typedef QStringList qcontainer_type;
typedef InputContainerType scontainer_type;
explicit back_insert_iterator(qcontainer_type& x)
: container(&x)
{ }
back_insert_iterator& operator=(scontainer_type::const_reference value) {
container->push_back(QString().fromStdString(value));
return *this;
}
back_insert_iterator& operator*() { return *this; }
back_insert_iterator& operator++() { return *this; }
back_insert_iterator operator++(int) { return *this; }
};
template<typename InputContainerType>
inline back_insert_iterator
back_inserter(QStringList& x) { return back_insert_iterator<InputContainerType>(x); }
}
Code: Alles auswählen
std::copy(first, last,std::back_inserter(qtstrlst));
-
QtBerserker
- Beiträge: 71
- Registriert: 15. Mai 2006 09:07
so einfach geht das leider nicht, zum einen klemmt's bei std::back_inserter(qtstrlst), da der Template Parameter dann QStringList wäre, zum anderen gibt es eine Neudefinition von template back_insert_iterator. Imo kommt man um eine Spezialiserung des back_insert_iterators nicht umhin - wenn man diesen Weg wählen möchte.
Olaf
Olaf
QStringList braucht man nicht als template argument, da es fest ist... Also, wo liegt das Problem?QtBerserker hat geschrieben:so einfach geht das leider nicht, zum einen klemmt's bei std::back_inserter(qtstrlst), da der Template Parameter dann QStringList wäre, zum anderen gibt es eine Neudefinition von template back_insert_iterator. Imo kommt man um eine Spezialiserung des back_insert_iterators nicht umhin - wenn man diesen Weg wählen möchte.
Olaf