¿Cómo funciona std :: visit con std :: variant?
Estoy mirandostd:variant/std::visit
doc aquí:http://en.cppreference.com/w/cpp/utility/variant/visit y también busqué mucho en Google tratando de entender la magia detrásstd::visit
ystd::variant
.
Entonces mi pregunta es la siguiente. En el ejemplo proporcionado, ambos en ellambda polimórfica y el "sobrecargado" está sucediendo algo de "magia" que permite extraer el tipo correcto destd::variant
.
Mirando esto:
for (auto& v: vec) {
std::visit(overloaded {
[](auto arg) { std::cout << arg << ' '; },
[](double arg) { std::cout << std::fixed << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
}, v);
}
Para cadav
, que es solo una variante, ¿cómo se invoca la función lambda sobrecargada correcta? Parece que hay algo de lógica que necesita descubrir el tipo exacto que posee el específicostd::variant
, emitirlo y enviarlo a la función adecuada. Mi pregunta es ¿cómo funciona? Mismo trato para esto:
std::visit([](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, int>)
std::cout << "int with value " << arg << '\n';
else if constexpr (std::is_same_v<T, long>)
std::cout << "long with value " << arg << '\n';
else if constexpr (std::is_same_v<T, double>)
std::cout << "double with value " << arg << '\n';
else if constexpr (std::is_same_v<T, std::string>)
std::cout << "std::string with value " << std::quoted(arg) << '\n';
else
static_assert(always_false<T>::value, "non-exhaustive visitor!");
}, w);
Pasamos lambda polimórfica al visitante como el objeto invocable yw
es una variante que puede contener int, long, double o std :: string. ¿Dónde está la lógica que determina el tipo correcto parausing T = std::decay_t<decltype(arg)>;
para recuperar el tipo real de la instancia específica de una variante?