How would I define a function that takes as input an iterator over any type of STL container, but only to those of a specific templated type. For example:
Any iterator of the form std::list<Unit*>::iterator
or std::vector<Unit*>::iterator
I would just define the function to take std::list<Unit*>::iterator
, but if we switch to a different STL container, I don't want to have to change my code.
Is there a way to do this with templates or otherwise?
5. prev() :- This function returns the new iterator that the iterator would point after decrementing the positions mentioned in its arguments. 6.
An iterator is used to point to the memory address of the STL container classes. For better understanding, you can relate them with a pointer, to some extent. Iterators act as a bridge that connects algorithms to STL containers and allows the modifications of the data present inside the container.
struct vec{ iterator begin() ; const_iterator begin() const; };
An iterator is an object (like a pointer) that points to an element inside the container. We can use iterators to move through the contents of the container. They can be visualised as something similar to a pointer pointing to some location and we can access content at that particular location using them.
You could use a SFINAE construct such as boost::enable_if which verifies if the nested typedef iterator::value_type
is indeed of the appropriate type.
template<class T, class Iterator>
typename boost::enable_if<boost::is_same<typename Iterator::value_type, T> >::type
f(Iterator i)
{
/* ... */
}
int main()
{
std::list<int> l;
std::vector<int> v;
f<int>(l.begin()); // OK
f<int>(v.begin()); // OK
std::vector<float> v2;
f<int>(v2.begin()); /* Illegal */
}
This is what I understand from "a function that takes as input an iterator over any type of STL container, but only to those of a specific templated type", but my interpretation might be wrong.
In addition to the existing answers relying on SFINAE, a simpler approximation would be to simply define the function to take an arbitrary template type as the iterator:
template <typename Iter>
void function(Iter first, Iter last){
Unit* val = *first;
}
This has a few downsides. Unlike the SFINAE solution (such as boost::enable_if
), this doesn't give you exactly what you asked for. This compiles as long as an object of type Iter
can be dereferenced yielding a value convertible to Unit*
, which isn't quite the same thing. You have no guarantee that Iter
is a completely STL-compliant iterator (it may just be another type which defines operator*
), or that its value type is Unit*
precisely.
On the other hand, it's much simpler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With