Suppose I have a class called Object. The Object class has a member function that wants to read in strings from a container. Suppose the function looks like this:
template <class InputIterator>
void Object::add(InputIterator first, InputIterator last) { ... }
While this allows the caller to pass strings from an arbitrary container, it does not express the fact that the iterators must be a pair of string iterators.
Is it still appropriate to use templates in this case, or should I force the caller to use a predetermined container of strings?
Unfortunately, C++ doesn’t at the moment allow you to codify such information in a concise way.
C++11 was supposed to solve this with concepts but they were chucked out before the release due to some conceptual (heh) deficiencies (which have in the meantime been solved, as far as I know).
But you can still provide such concepts using static assertion and type traits. C++11 for instance allows to write the following code:
template <class InputIterator>
void Object::add(InputIterator first, InputIterator last) {
static_assert(
std::is_same<
typename std::remove_cv<
typename std::iterator_traits<InputIterator>::value_type
>::type,
std::string>::value,
"InputIterator must be of iterator type");
…
}
Still, this assumes that InputIterator
is a valid iterator type. Since there is no trait is_iterator
and no meaningful way to implement this (as far as I know) except by checking that all required operations of an input iterator are obeyed, this makes it far more difficult than it could theoretically be.