Reputation: 231
I need to develop an algorithm for a library that receives a "list of strings".
Of course I want to pass an "abstract" iterator to decouple the internal representation of that list (a vector, a linked list, a map...) to the access to it from my function.
This is my approach:
template <typename ForwardIterator>
void myAlgorithm(ForwardIterator itBegin, ForwardIterator itEnd) {
for(; itBegin != itEnd ; ++itBegin) {
// Do something with *itBegin
}
}
My question is, how can I restrict the type of the container to be string? Or even more, is there some way of accepting both std::strings and char* as elements?
Thanks a lot.
Upvotes: 2
Views: 173
Reputation: 263088
You can use std::enable_if
to restrict the possible template arguments:
#include <type_traits>
#include <iterator>
template <typename ForwardIterator>
typename std::enable_if<
std::is_same<
typename std::iterator_traits<ForwardIterator>::value_type,
std::string
>::value, void
>::type
myAlgorithm(ForwardIterator itBegin, ForwardIterator itEnd) {
for(; itBegin != itEnd ; ++itBegin) {
// Do something with *itBegin
}
}
Although I don't really see the point in this restriction.
Is there some way of accepting both std::strings and char* as elements?
Sure, just replace std::is_same
with std::is_convertible
.
Upvotes: 3
Reputation: 62975
Use a static assertion along with std::iterator_traits<>
:
template<typename ForwardIterator>
void myAlgorithm(ForwardIterator itBegin, ForwardIterator itEnd) {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_t;
BOOST_STATIC_ASSERT((
boost::is_same<value_t, std::string>::value ||
boost::is_same<value_t, char const*>::value
));
for(; itBegin != itEnd ; ++itBegin) {
// Do something with *itBegin
}
}
If you're using a C++0x compiler, you can use static_assert
instead of BOOST_STATIC_ASSERT
and std::is_same
instead of boost::is_same
.
Upvotes: 5