Say the following variant
is given:
using Variant = std::variant<uint32_t*, uint16_t*>
And then, a vector
of such variant
s is needed:
using VariantVecType = std::vector<Variant>
How would one go about accessing the underlying values (pointed to by those pointers) to perform arithmetic operations on them in a more generic way (i.e. without using std::get_if
) e.g.
uint32_t i0 = 1;
uint16_t i1 = 2;
Variant v0{ &i0 };
Variant v1{ &i1 };
VariantVecType vec{v0, v1};
for(auto& v : vec)
if(auto pval = std::get_if<uint32_t*>(&v))
std::cout << "Underlying int value: " << *(*pval) << '\n';
else if(auto pval = std::get_if<uint16_t*>(&v))
std::cout << "Underlying int value: " << *(*pval) << '\n';
else
std::cout << "failed to get value!" << '\n';
Usually you would use std::visit
example
#include <iostream>
#include <variant>
#include <cstdint>
#include <vector>
// from cppref:
// helper type for the visitor #4
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
// explicit deduction guide (not needed as of C++20)
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
int main() {
uint32_t i0 = 1;
uint16_t i1 = 2;
using Variant = std::variant<uint32_t*, uint16_t*>;
Variant v0{ &i0 };
Variant v1{ &i1 };
using VariantVecType = std::vector<Variant>;
VariantVecType vec{v0, v1};
for(auto& v : vec) {
std::visit(overloaded {
[](uint32_t* arg) { std::cout << "Underlying uint32 value: " << *arg << '\n'; },
[](uint16_t* arg) { std::cout << "Underlying uint16 value: " << *arg << '\n'; },
}, v);
}
}
But a std::variant<uint32_t*, uint16_t*>
seems a bit awkward. pointers in 64-bit machines are bigger then both types. And accessing the elements requires indirection=slow. Plus the arithmetic on both types will be about the same (except for overflow). So why not have a normal std::vector<uint32_t>
?