Let's say that I would like to write universal function that prints out the standard output range from a collection. Since it supposed to be universal I assume that...
std::vector<std::string> names = { "John", "Henry", "Mark" };
as well as:
std::vector<int> years = { 100, 200, 400 };
.. will be possible to printed out.
Since types of collection may be different, and there is not base class for STL collection giving me chance to pass base class iterators I use template function:
template<typename TIterator>
void PrintRange( TIterator beginIter,TIterator endIter )
{
for( auto it = beginIter; it != endIter; ++it )
{
std::cout << *it << std::endl;
}
}
Everything now works well, now I can write:
PrintRange( names.begin(), names.end() );
and:
PrintRange( years.begin(), years.end() );
But now I want to help client of my function to faster understand why there is an error when he use it. Now when I call:
PrintRange( 100, 400 );
There is error:
main.cpp:23:34: error: invalid type argument of unary ‘*’ (have ‘int’)
I would like to print something like:
One of arguments does not correspond to expected argument of type 'iterator'
So what approach to this problem is best:
It's not important to care that the error message is not as meaningful as I expected. User should analyse template class code to establish reason of his mistake.
Use static_assert to assert all know possibilities.. but how to assert that the argument of function is ANY iterator since there is no base class?
static_assert( std::is_base_of::iterator >::value );
This would only assert vector of string iterator...