2010-05-18 15 views
5

Mam arbitralny kontener STL C, który zawiera elementy dowolnego typu T. Chcę utworzyć wektor std :: vector zawierający kopię wszystkich elementów. Jaki jest najczystszy sposób na zrobienie tego?Szablony funkcji dla dowolnych kontenerów STL zawierających typy arbitralne

template <typename C> 
void myfunction(C container){ 

    /*Derive the type T of elements within the container*/ 

    std::vector<T> mystack; 

    /* Iterate over container and push_back() the elements into mystack*/ 
} 

Odpowiedz

11

struktury STL jak vector i set powinien zawierać typ value_type który jest typedef ED do T.

std::vector<typename C::value_type> mystack; 

BTW, nie trzeba samemu dokonywać iteracji po pojemniku. Po prostu użyj

+0

Pomyślałem, że wpadnę na to w C++ 11. Czy nowe słowo kluczowe "auto" działałoby tutaj? Nie miałem okazji się z tym bawić. –

+0

@ChadBrewbaker: Nie. 'Decltype' będzie działać, ale to nie jest prostsze niż' nazwa_klasy C :: value_type'. – kennytm

10

Dla pojemników, Kenny podał prawidłowe rozwiązanie. Jednak wiele funkcji w C++ pobiera pary iteratorów zamiast kontenerów ... ta sama logika może być tutaj zastosowana. Iteratory używać iterator_traits do przekazywania informacji o swoich powiązanych typów:

template <typename It> 
void myfunction(It start, It end) { 
    // Get value for iterator: 

    typedef typename std::iterator_traits<It>::value_type T; 

    // Do something, e.g. calculate the minimum: 

    T min_value = *std::min_element(start, end); 
} 

przy okazji, typename jest konieczne w typedef ponieważ value_type jest tzw zależny typ, czyli to zależy od charakteru szablonu argumentu a kompilator C++ nie może samodzielnie stwierdzić, że odnosi się do nazwy typu (zamiast, powiedzmy, statycznej metody lub zmiennej) w tym kontekście.

+3

To jest miły dodatek do odpowiedzi Kenny'ego, chociaż czułbym się znacznie lepiej o moim głosowaniu w górę, gdybyś nie nazwał iteratora wskazującego _one przekazał ostatni prawidłowy element_, taki sam jak zwykła funkcja członka kontenera, pobierająca ostatni poprawny element. To bardzo duży potencjał do pomyłek. – sbi

+0

@sbi: ** D'oh! ** Użyłem tej notacji w moim własnym kodzie konsekwentnie * od lat * i nigdy nie zauważyłem, że to tak źle wpływa na użycie STL. Złe, złe, złe. :-( –

+0

Używam 'first',' last', jak robią to algorytmy STL. Musisz sobie poradzić z tym, że "last" jest ostatnim iteratorem * zakresu, a nie iteratorem, który wskazuje na ostatni element * w * zakresie: –

Powiązane problemy