Reputation: 384
I am struggling a bit with passing iterators to functions.
I want to accomplish something like this. void func(MyClass* foo, numberOfFoo);
But I want to use iterators and it should support any stl-container.
I know I can write a function like this:
void foo(std::vector<MyClass>::const_iterator start, std::vector<MyClass>::const_iterator end){
while (start != end){
//Do stuff with *start, which has type MyClass
++start;
}
}
I also know that I can write a Template like this:
template <class Iterator>
void foo( Iterator first, Iterator last){
while (start != end){
//Do stuff with *start, which has ANY type
++start;
}
}
But I now want to write a Template, where the data type of the iterators are of type MyClass and no other.
In the end the following should happen:
std::vector<MyClass> vectorOfClass;
std::array<MyClass> arrayOfClass;
std::vector<int> vectorOfInt;
foo(vectorOfClass.begin(), vectorOfClass.end()); //Should compile
foo(arrayOfClass.begin(), arrayOfClass.end()); //Should compile
foo(vectorOfInt.begin(), vectorOfInt.end()); //Should not compile
Maybe the solution is very easy, but I don't know what to search for.
Thanks for your help already.
Upvotes: 1
Views: 133
Reputation: 117258
If you don't need overloads, you don't need SFINAE, and could go for a simple static_assert
using std::is_same_v
and std::iterator_traits
. A static_assert
makes it possible to generate a really clear compilation error.
#include <iterator> // std::iterator_traits
#include <type_traits> // std::is_same_v
template<class It>
void foo(It first, It last) {
static_assert(std::is_same_v<class std::iterator_traits<It>::value_type, MyClass>,
"Only ranges of MyClass objects are accepted by foo()");
//...
}
Upvotes: 3