Pytanie Deklaracja funkcji akceptującej ogólny iterator


Biorąc pod uwagę ten kod, można go zmienić dumpStrings() aby móc iterować nad dowolnym kontenerem string, jak powiedzmy list<string> ?

#include <vector>
#include <string>
#include <ostream>
#include <iostream>

using namespace std;

void dumpStrings(vector<string>::iterator it, vector<string>::iterator end)
{
    while (it != end) {
        cout << *it++ << endl;
    }
}

int main()
{
    vector<string> strVector;
    strVector.push_back("Hello");
    strVector.push_back("World");

    dumpStrings(strVector.begin(), strVector.end());
    return 0;
}

17
2018-02-19 23:01


pochodzenie


Dlaczego nawet ograniczyć go do ciągów? Może po prostu template <typename Iterator> dump(Iterator first, Iterator last);? - GManNickG
To tylko przykład. Mam coś, co zużywa ciąg i tylko ciąg. Nie chcę pozwolić na inny przedmiot. - Simon P.


Odpowiedzi:


tak

http://www.boost.org/doc/libs/1_45_0/libs/utility/enable_if.html

http://www.cplusplus.com/reference/std/iterator/iterator_traits/

http://www.boost.org/doc/libs/1_44_0/libs/type_traits/doc/html/boost_typetraits/reference/is_same.html

template<class I>
typename enable_if<
    is_same<typename iterator_traits<I>::value_type, string>
    >::type
function(...

12
2018-02-19 23:08



Dzięki. Wygląda na to, że jest najbliżej tego, co chcę. Trochę bardziej skomplikowałem, niż chciałem. - Simon P.
FYI, jest to teraz możliwe w C ++ 11 ze std :: is_same. - Ben Sidhom


Utwórz szablon

template<class iterator_type>
void dumpStrings(iterator_type it, iterator_type end)
{
    while (it != end) {
        cout << *(it++) << endl;
    }
}

Szablon usuwa także ograniczenie typu wartości kontenera do łańcucha. Zwróć uwagę, że potrzebujesz nawiasów wokół niego ++.


19
2018-02-19 23:07



Chociaż myślę, że to najlepsze rozwiązanie, nie jest to odpowiedź na jego pytanie. (Powinieneś przynajmniej zakwalifikować swoją odpowiedź słowami "Dlaczego ograniczyć ciągi?" Lub czymś, aby było jasne, że wybierasz mniej konkretną trasę.) - GManNickG


Nie sądzę, żeby było coś tak prostego, jak byś chciał. Idealnie, możesz po prostu zrobić coś takiego

void dumpStrings(AbstractIterator<string> beg, AbstractIterator<string> end) { }

ale iteratory STL nie wydają się posiadać żadnej hierarchii dziedziczenia, irytująco. Wygląda na to, że utknąłeś z użyciem szablony funkcji - tak to się dzieje w Biblioteka algorytmów STL.

Przepraszam - szkoda, że ​​nie było lepszego sposobu, ale to musi wystarczyć. Pamiętaj tylko, aby zadeklarować pełny szablon funkcji w pliku nagłówkowym!


1
2018-02-19 23:19





Spróbuj tego, działałoby to we wszystkich kontenerach:

template<class T>
void disp(T &t)
{
    for( auto itr=t.begin();itr!=t.end();itr++)
        cout<<*itr<<endl;
}

.cpp
    vector<int> v(3,77);
    list<string> l(5,"Hello");
    disp(l)
    disp(v);

Uwaga: nie zapomnij uwzględnić <strunowy>,
      A auto jest dostępne w c ++ 11


-1
2017-08-01 07:13