I have the code below and why visitor1
and visitor2
gives errors?
Does that mean the visitor cannot return one type within the variant?
#include <iostream>
#include <variant>
struct Visitor1
{
template <class T>
T operator()(const T & t) const
{
return (t);
}
};
struct Visitor2
{
int operator()(const int & t) const
{
return std::get<int>(t);
}
char operator()(const char & t) const
{
return std::get<char>(t);
}
};
struct Visitor3
{
void operator()(const int & t) const
{
std::cout<<t;
}
void operator()(const char & t) const
{
std::cout<<t;
}
};
int main()
{
std::variant<int, char> v{char(100)};
std::visit(Visitor3{}, v);
auto t = std::visit(Visitor2{}, v); //fails
//auto t = std::visit(Visitor1{}, v); //fails
std::cout << t;
}
I know I can use std::get()
, but the issue is I can only use auto
with std::get()
, if I do something like below, the x
is not accessible outside of the if/else scope:
bool b;
Variant v;
if (b)
{
auto x = std::get<int>(v);
}
else
{
auto x = std::get<char>(v);
}
// I want to do something with x here out of if/else
Because C++ is a strongly typed language.
When you write
the compiler must decide compile-time which type is
t
, so must decide which type returnstd::visit(Visitor2{}, v)
.If
Visitor2
return achar
, whenv
contains achar
, or aint
, whenv
contain aint
, the compiler can't choose (compile-time!) the type returned fromstd::visit()
[there is also the problem (Visitor2
only) thatt
, insideoperator()
's, is aint
or achar
, so you can't applystd::get()
to it].Same problem with
Visitor1
: the templateoperator()
return the template type soint
orchar
for astd::variant<int, char>
.Visitor3
works because bothoperator()
returnvoid
, so the compiler can resolve (compile-time) thatstd::visit(Visitor3{}, v)
return (in a sense)void
.Maybe is better explained in this page: