I’d like to write operator<<
for std::variant
. The assumption will be that the operator<<
for a particular variant will only be valid if operator<<
is valid for all the types that the variant can contain.
Asked
Active
Viewed 1,624 times
10

Jarod42
- 203,559
- 14
- 181
- 302

Robert Fisher
- 578
- 4
- 20
1 Answers
14
//g++ (GCC) 7.2.0
//g++ -std=c++1z -O2 -Wall -pedantic -pthread main.cpp
#include <iostream>
#include <string>
#include <variant>
#include <complex>
template<typename T, typename... Ts>
std::ostream& operator<<(std::ostream& os, const std::variant<T, Ts...>& v)
{
std::visit([&os](auto&& arg) {
os << arg;
}, v);
return os;
}
int main()
{
using namespace std::complex_literals;
std::variant<int, std::string, double, std::complex<double>> v = 4;
std::cout << v << '\n';
v = "hello";
std::cout << v << '\n';
v = 3.14;
std::cout << v << '\n';
v = 2. + 3i;
std::cout << v << '\n';
}
This relies on passing a generic lambda to std::visit
.
See this question for a problem with the previous version of this answer. This answer has been updated to avoid that problem.

Robert Fisher
- 578
- 4
- 20
-
4Can't you just use `template
std::ostream& operator<<(std::ostream& os, const std::variant – Caleth Oct 23 '17 at 15:35& v)`? -
@Caleth, actually no. He can't, because of https://stackoverflow.com/q/52845621/225186 . The sfinae version was correct. – alfC Oct 17 '18 at 02:11
-
@alfC just adding a typename in front of the pack will suffice `template
` – Caleth Oct 17 '18 at 08:21 -
So, the possible fixes are: (1) Restore the SFINAE. (2) Change `variant
` to `variant – Robert Fisher Oct 17 '18 at 12:55`. (3) Add `typename`. (4) Call it a compiler bug and change nothing. I'm tempted to go with 3, but I'm kind of feeling like it should first be added as an answer to [the new question](https://stackoverflow.com/q/52845621/225186) and discussed with the other solutions there. -
@RobertFisher, what is (3)? (4) It is not a compiler bug. – alfC Oct 17 '18 at 15:17
-
@alfC Hmm...regarding (3), maybe I was confused about Caleth's comment about "adding a typename...will suffice". (I wish comments could be threaded, even if we don't want it to become chat.) Regarding (4), I now see that Barry described it as a “language bug” instead of a compiler bug. I misread that. So, I guess (2) is the best choice? – Robert Fisher Oct 17 '18 at 15:26
-
@Caleth, Yes, that would also work, it is what I proposed in my answer https://stackoverflow.com/a/52846061/225186 – alfC Oct 17 '18 at 15:28
-
@RobertFisher It would be helpful to make the code you supplied work, it is different to the code in the "Demo" link and doesn't compile. – Jesse Pepper May 20 '20 at 07:12