Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function templates for arbitrary STL containers containing arbitrary types

I have an arbitrary STL container C, which contains elements of an arbitrary type T. I want to create an std::vector that has a copy of all the elements. What is the cleanest way to do this?

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*/
} 
like image 302
Chad Brewbaker Avatar asked May 18 '10 18:05

Chad Brewbaker


2 Answers

STL structures like vector and set should contain the value_type type that is typedef-ed to T.

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

BTW, you don't need to iterate over the container yourself. Just use

template <typename C>
void myfunction(const C& container){
  std::vector<typename C::value_type> mystack(container.begin(), container.end());
  ...
}
like image 168
kennytm Avatar answered Nov 01 '22 22:11

kennytm


For containers, Kenny has given the correct solution. However, many functions in C++ take pairs of iterators instead of containers … the same logic can be applied here. Iterators use iterator_traits to provide information about their related types:

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

By the way, typename is necessary in the typedef because value_type is a so-called dependent type, i.e. it depends on the nature of a template argument and the C++ compiler cannot figure out on its own that it refers to a type name (rather than, say, a static method or variable) in this context.

like image 39
Konrad Rudolph Avatar answered Nov 01 '22 23:11

Konrad Rudolph