Reputation: 11944
Sorry for the trivial question, but I could not Google this with a couple of attempts and decided to ask here. What is the proper way to specify the template parameters in this case:
#include <sstream>
struct bar
{
int foo = 5;
};
template<size_t i>
std::ostream& operator<<(std::ostream& s, bar b)
{
s << b.foo + i;
return s;
}
int main(int argc, char** argv)
{
std::stringstream s;
bar b;
// Proper way of writing s << bar ?
return 0;
}
Upvotes: 1
Views: 52
Reputation: 21576
Since your function template has no deducable argument, you will have to explicitly call it with the template argument. Its ugly.
operator << <4>(s, b);
Another ugly hack is to use a proxy template-class:
template<std::size_t K>
struct bT{
bT(bar& bb) : b(bb) {} bar& b;
static constexpr std::size_t i = K;
};
Then modify your template operator <<
to:
template<size_t i>
std::ostream& operator<<(std::ostream& s, bT<i> b)
{
s << b.b.foo + b.i;
return s;
}
And call like:
s << bT<4>(b);
Demo.. Anyhow we panel beat this, it still ends up being ugly. Save everyone the stress, and use a named function. That will be more legible an intuitive.
Upvotes: 1
Reputation: 41100
You are forced to use the long form to call the operator, and explicitly pass template parameters
int main()
{
std::stringstream s;
bar b;
::operator<<<1>(s, b);
return 0;
}
The ::operator<<<1>(s, b);
syntax looks weird, but focus on the ::operator<<
portion, which is referencing the operator in the global namespace. Since you've written it as a template, and the template parameter (size_t
) cannot be inferred from the arguments, you are forced to use an explicit template parameter in the form of <1>
(<2>
, <3>
, etc.)
Upvotes: 3