I'm playing around with variadic templates, and wrote this, based on this answer :
template <size_t... I>
void print(seq<I...>)
{
decltype(std::cout) * dummy[sizeof...(I)] = { &(std::cout << I << ' ')... };
}
Because std::cout::operator<<
has a return type, it can be stored, so there's no need for the ( ,0)
comma trick.
Now, to shut up the "unused variable 'dummy'" warning, and to print a newline, I tried the following statements, but they didn't do what I wanted:
dummy[0]->operator <<('\n'); // prints 10
(apparently called operator<<(int)
instead of operator<<(char)
dummy[0]->operator <<("\n"); // prints a pointer
(apparently called operator<<(const void*)
instead of operator<<(const char*)
In the end, I had to write
*dummy[0] << '\n'; // prints a newline as desired
My question is, why did the "wrong" overloads get chosen?
The "wrong" overloads are chosen because only some overloads are members of std::ostream
class. The overloads for char
and const char*
are not members of std::ostream
, but free functions, so, in
*dummy[0] << '\n';
argument-dependent lookup will find operator<<(std::ostream&, char)
, but in
dummy[0]->operator <<('\n');
only member functions will be considered, resulting in std::ostream::operator<<(int)
being called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With