Pass iterator instead of container

c++, containers, iterator

Solution

For C++03:

#include <iterator>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/utility/enable_if.hpp>

template<typename InputIterator>
typename boost::enable_if<
    boost::is_same<
        typename boost::remove_cv<
            typename std::iterator_traits<InputIterator>::value_type
        >::type,
        double // expected value_type
    >,
    double     // fooB return type
>::type
fooB(InputIterator first, InputIterator last)
{
    return *first;
}

Another C++03 solution which doesn't use Boost, but will likely produce much uglier errors when passing an invalid type:

#include <iterator>

void fooB_helper(double) { }
template<typename T> void fooB_helper(T const&);

template<typename InputIterator>
double fooB(InputIterator first, InputIterator last)
{
    fooB_helper(typename std::iterator_traits<InputIterator>::value_type());
    return *first;
}

For C++11 you can use expression SFINAE instead of `enable_if`, or you can use `static_assert` instead of SFINAE altogether.

Problem

Currently, I'm stuck with some code like `fooA()` (don't mind the body) which expects a specific container, say `vector<double>`, as argument. ``` double fooA(std::vector<double> const& list) { return list[0]; } ``` Now, I want to generalize and use iterators instead: ``` template<typename InputIterator> double fooB(InputIterator first, InputIterator last) { return *first; } ``` How to state that `fooB()` requires the iterator to iterate over `double`? Someone might pass a `vector<string>::iterator` or, even worse as it might compile without a warning, a `vector<int>::iterator`.

Original source