Frage

Ich versuche, entgegengesetzte Wirkung auf diese zu codieren:

std::ostream outs; // properly initialized of course
std::set<int> my_set; // ditto

outs << my_set.size();
std::copy( my_set.begin(), my_set.end(), std::ostream_iterator<int>( outs ) );

es sollte wie folgt sein:

std::istream ins;

std::set<int>::size_type size;
ins >> size;

std::copy( std::istream_iterator<int>( ins ), std::istream_iterator<int>( ins ) ???, std::inserter( my_set, my_set.end() ) );

Aber ich bin fest mit dem ‚Ende‘ Iterator - Eingang interators nicht std :: Fortschritt und weder ich kann zwei Ströme mit der gleichen Quelle verwenden ...

Gibt es eine elegante Art und Weise, wie diese zu lösen? Natürlich kann ich für Schleife verwenden, aber vielleicht gibt es etwas schöneres:)

War es hilfreich?

Lösung

Sie können von der istream_iterator ableiten .
Obwohl mit ist Daemin Generator Methode eine weitere Option direkt in die Menge, obwohl ich eher erzeugen würde, als einen Zwischenvektor verwendet werden.

#include <set>
#include <iterator>
#include <algorithm>
#include <iostream>


template<typename T>
struct CountIter: public std::istream_iterator<T>
{
    CountIter(size_t c)
        :std::istream_iterator<T>()
        ,count(c)
    {}
    CountIter(std::istream& str)
        :std::istream_iterator<T>(str)
        ,count(0)
    {}

    bool operator!=(CountIter const& rhs) const
    {
        return (count != rhs.count) && (dynamic_cast<std::istream_iterator<T> const&>(*this) != rhs);
    }
    T operator*()
    {
        ++count;
        return std::istream_iterator<T>::operator*();
    }

    private:
        size_t  count;
};

int main()
{
    std::set<int>       x;

    //std::copy(std::istream_iterator<int>(std::cin),std::istream_iterator<int>(),std::inserter(x,x.end()));
    std::copy(
                CountIter<int>(std::cin),
                CountIter<int>(5),
                std::inserter(x,x.end())
            );
}

Andere Tipps

Verwendung:

std::copy( std::istream_iterator<int>(ins),
           std::istream_iterator<int>(),
           std::inserter(my_set, my_set.end())
         );

Beachten Sie die leeren Parameter:

std::istream_iterator<int>();

Errr ... copy_n () Algorithmus?

diesen Blick in einem wenig glaube ich nicht direkt in einen Satz zu lesen funktionieren werde, wie Sie Einsatz auf sie anrufen müssen, um tatsächlich die Elemente hinzufügen (Ich könnte falsch sein, ist es ziemlich früh am Morgen hier). Obwohl Blick auf der STL-Dokumentation in VS2005 kurz denke ich, etwas mit der generate_n Funktion funktionieren soll, zum Beispiel:

std::istream ins;
std::set<int> my_set;
std::vector<int> my_vec;

struct read_functor
{
    read_functor(std::istream& stream) :
        m_stream(stream)
    {
    }

    int operator()
    {
        int temp;
        m_stream >> temp;
        return temp;
    }
private:
    std::istream& m_stream;
};

std::set<int>::size_type size;
ins >> size;
my_vec.reserve(size);

std::generate_n(my_vec.begin(), size, read_functor(ins));
my_set.insert(my_vec.begin(), my_vec.end());

Hoffentlich ist das entweder gelöst Ihr Problem, oder Ihnen davon überzeugt, dass die Schleife in dem großen Plan der Dinge nicht so schlecht ist.

Wie wäre es eine alternative Iterator mit dem Traversal zu tun und dann ein Funktionsobjekt (oder Lambda) verwenden in den Behälter zu füllen?

istream ins;
set<int>::size_type size;
set<int> new_set;
ins >> size;
ostream_iterator<int> ins_iter(ins);

for_each(counting_iterator<int>(0), counting_iterator<int>(size),
  [&new_set, &ins_iter](int n) { new_set.insert(*ins_iter++); }
);

Dies ist natürlich vorausgesetzt, dass Sie einen C ++ 0x-konformen Compiler.

BTW, 'counting_iterator <>' ist ein Teil von Boost.Iterator .

Oder Sie könnten dies tun:

my_set.insert(std::istream_iterator<int>(ins), std::istream_iterator<int>());

Ja sdg aber wenn ich will eine andere Datenstrukturen in der Datei / Stream benutzen? Ich soll wohl hier explizit schreiben, ich will nach diesem Satz eines anderen Sachen speichern, das ist der Grund, warum ich die Größe als auch mich zu speichern.

(Edited: Ich soll die Frage näher haben lesen ...)

Während etwas suspekt, können Sie etwa das richtige Verhalten erhalten, indem Sie einen Eintrag in der Datei hat, die „nicht bestanden“ die erste Schleife, dann deaktivieren Sie das Bit nicht auf den Strom und beginnen, mehr zu lesen.

Daten, ohne eine explizite Größe, aber ich mag diese

1 1 2 3 5 8 Fibb

Fed auf den Code unten scheint zu tun, was ich meinte, zumindest auf VS2005 mit STLPort.

typedef std::istream_iterator < int, char, std::char_traits ,ptrdiff_t> is_iter;
std::copy( is_iter(cin), is_iter(), inserter(my_set,my_set.end()));
cin.clear();
std::cin >> instr;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top