以通用方式对 std::variant<POD_PTR*...> 执行操作

Perform operations on std::variant<POD_PTR*...> in a generic way

假设给出以下 variant
using Variant = std::variant<uint32_t*, uint16_t*>

然后,需要 vector 个这样的 variants:
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>呢?