Reputation: 103
I Have the following code:
template <typename Iter, typename STREAM>
void print(Iter b, Iter e, STREAM& strm)
{
while (b != e)
{
strm << *b;
strm << " ";
++b;
}
strm << "\n";
}
How to have default value for strm = std::cout
?
Upvotes: 3
Views: 129
Reputation: 217275
You have to provide default for type and for argument:
template <typename Iter, typename STREAM = std::ostream>
void print(Iter b, Iter e, STREAM& strm = std::cout);
As std::cout
is not a good default value for other STREAM
, you probably need to change the default:
template <typename STREAM>
STREAM& DefaultStream;
template <>
std::ostream& DefaultStream<std::ostream> = std::cout;
and then
template <typename Iter, typename STREAM = std::ostream>
void print(Iter b, Iter e, STREAM& strm = DefaultStream<STREAM>);
Upvotes: 2
Reputation: 10982
Note that you can also use
template <typename Iter, typename STREAM = decltype(std::cout)>
void print(Iter b, Iter e, STREAM& strm = std::cout)
{
while (b != e)
{
strm << *b;
strm << " ";
++b;
}
strm << "\n";
}
This works with c++11, but I think that @AsteroidsWithWings's solution is the right way to go (as it is simpler and avoid the necessary redundancy required to define both the template type and argument value)
Upvotes: 1
Reputation: 17454
If you were to just add = std::cout
, you'd need to provide the template argument std::ostream
explicitly when calling the function with two arguments, which is a bit rubbish.
The easiest way to do what you want is to provide a new overload:
template <typename Iter>
void print(Iter b, Iter e)
{
print(b, e, std::cout);
}
You could also consider getting rid of STREAM
entirely; you usually only ever want to stream to a std::ostream
. There's a reason a bunch of useful types inherit from it.
Upvotes: 5