问题描述
说出下面的variant
:using Variant = std::variant<uint32_t*,uint16_t*>
然后,需要 vector
个这样的 variant
:using VariantVecType = std::vector<Variant>
如何访问底层值(由这些指针指向)以更通用的方式(即不使用 std::get_if
)对它们执行算术运算,例如
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';
解决方法
通常您会使用 std::visit
示例
#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);
}
}
但是 std::variant<uint32_t*,uint16_t*>
似乎有点尴尬。 64 位机器中的指针比这两种类型都大。并且访问元素需要indirection=slow。另外,这两种类型的算术将大致相同(溢出除外)。那么为什么没有一个正常的 std::vector<uint32_t>
?