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

如何更简洁地指定从std::variant获取的类型,避免重复代码?

解决方案

通过一个零开销的泛型封装即可实现符合要求的写法,既满足DRY原则,又完全保留原有异常逻辑,不会触发隐式类型转换。

实现代码

先定义通用的精确取值模板函数,所有逻辑在编译期展开,无额外运行时成本:

#include <variant>

template <typename T, typename... Ts>
T get_exact(const std::variant<Ts...>& v) {
    return std::get<T>(v);
}

初始化代码可简化为如下形式,无需重复书写类型、无需使用decltype:

std::variant<float, int> v[2] = foo();
int a = get_exact(v[0]);
float b = get_exact(v[1]);

行为特性

  • 异常逻辑与原代码完全一致:variant存储类型和目标变量类型不精确匹配时,会正常抛出std::bad_variant_access,原有异常处理逻辑无需修改。
  • 无隐式类型转换:如果variant存储float,尝试赋值给int变量时会直接抛出异常,不会触发static_cast类的数值转换,完全符合要求。
  • 自动类型推导:编译器会根据赋值目标的类型自动确定std::get的模板参数,无需重复书写类型名,解决DRY违规问题。
  • 额外编译期检查:如果目标变量类型不在variant的备选类型列表中,编译阶段就会报错,安全性比原写法更高。
  • 零性能损耗:模板实例化后的代码与手写std::get<int>(v[0])、std::get<float>(v[1])完全等价,无任何额外开销。

补充

C++20及以上环境可以选择在局部用lambda实现相同逻辑,但独立泛型函数的复用性更高。标准库没有提供对应原生能力,因为std::get的模板参数仅通过入参推导,不会根据返回值的赋值目标倒推类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:36:16