You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用std::variant重构向量运算的嵌套switch语句?

用std::variant实现简洁的向量加法

要替代原来基于union和嵌套switch的冗余代码,核心是利用std::visit自动处理std::variant的类型分支,结合模板函数复用不同向量类型的加法逻辑。

步骤1:实现通用向量加法模板

先写一个模板函数,统一处理同类型向量的加法逻辑,避免重复代码:

#include <variant>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <functional>

template<typename T>
std::vector<T> vector_add(const std::vector<T>& lhs, const std::vector<T>& rhs) {
    if (lhs.size() != rhs.size()) {
        throw std::invalid_argument("Vectors must have the same size");
    }
    std::vector<T> result;
    result.reserve(lhs.size());
    std::transform(lhs.begin(), lhs.end(), rhs.begin(),
                   std::back_inserter(result), std::plus<T>());
    return result;
}

步骤2:实现add函数(严格类型匹配)

如果要求只能相加同类型的向量,用std::visit配合constexpr if做编译期类型检查:

using Data = std::variant<std::vector<int>, std::vector<float>, std::vector<double>>;

Data add(const Data& lhs, const Data& rhs) {
    return std::visit([](const auto& l_vec, const auto& r_vec) -> Data {
        using LVecType = std::decay_t<decltype(l_vec)>;
        using RVecType = std::decay_t<decltype(r_vec)>;
        
        if constexpr (std::is_same_v<LVecType, RVecType>) {
            return vector_add(l_vec, r_vec);
        } else {
            throw std::invalid_argument("Cannot add vectors of different element types");
        }
    }, lhs, rhs);
}

可选:支持不同类型向量相加(自动转换)

如果需要支持不同数值类型的向量相加(比如int和float),可以利用std::common_type_t推导共同类型,实现混合加法:

// 混合类型向量加法模板
template<typename T, typename U>
std::vector<std::common_type_t<T, U>> mixed_vector_add(const std::vector<T>& lhs, const std::vector<U>& rhs) {
    if (lhs.size() != rhs.size()) {
        throw std::invalid_argument("Vectors must have the same size");
    }
    using CommonType = std::common_type_t<T, U>;
    std::vector<CommonType> result;
    result.reserve(lhs.size());
    std::transform(lhs.begin(), lhs.end(), rhs.begin(),
                   std::back_inserter(result), [](const T& a, const U& b) {
                       return static_cast<CommonType>(a) + b;
                   });
    return result;
}

// 支持混合类型的add函数
Data add(const Data& lhs, const Data& rhs) {
    return std::visit([](const auto& l_vec, const auto& r_vec) -> Data {
        return mixed_vector_add(l_vec, r_vec);
    }, lhs, rhs);
}

测试示例

#include <iostream>

int main() {
    // 同类型相加
    Data int_vec1 = std::vector<int>{1, 2, 3};
    Data int_vec2 = std::vector<int>{4, 5, 6};
    auto int_result = add(int_vec1, int_vec2);
    std::visit([](const auto& vec) {
        std::cout << "Int vector sum: ";
        for (auto num : vec) std::cout << num << " ";
        std::cout << "\n";
    }, int_result);

    // 混合类型相加
    Data float_vec = std::vector<float>{1.5f, 2.5f};
    Data double_vec = std::vector<double>{3.0, 4.0};
    auto mixed_result = add(float_vec, double_vec);
    std::visit([](const auto& vec) {
        std::cout << "Mixed vector sum: ";
        for (auto num : vec) std::cout << num << " ";
        std::cout << "\n";
    }, mixed_result);
}

为什么这比嵌套switch好?

  • 无需手动编写大量重复的switch分支,新添加向量类型时只需扩展Data的variant类型,加法逻辑无需修改
  • 编译期类型检查,比union更安全,不会出现非法类型访问
  • 模板函数复用了所有数值类型向量的加法逻辑,代码简洁易维护

内容的提问来源于stack exchange,提问作者Louis Strous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:25:32