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`.