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

在std::visit内调用std::get导致std::variant报错,此行为是预期的吗?

问题分析与解决

你的代码编译错误的核心原因是**decltype(var_impl)得到的是引用类型**(比如const int&),但std::get的模板参数需要匹配std::variant中声明的原始类型(int或double),而不是带引用/const限定的版本。

当你调用std::get<decltype(var_impl)>(a.var)时,编译器尝试查找variant<int, double>中是否存在const int&这个备选类型——显然不存在,于是触发了静态断言T must occur exactly once in alternatives的错误。

修正方案

其实你完全不需要再调用std::get,因为std::visit已经把当前variant中存储的对象以引用形式传递给了lambda的参数var_impl,直接使用它即可:

#include <iostream>
#include <variant>

struct A 
{
    std::variant<int, double> var;
    
    A(int a) : var(a) {};
    A(double a) : var(a) {};
};

int main()
{
    auto a = A(1);
    const auto & v = a.var;
    
    std::visit([&](const auto & var_impl) {
        // 直接使用传入的var_impl,无需再get
        std::cout << var_impl << std::endl;
    }, v);

    return 0;
}

如果你确实需要通过类型获取(比如要初始化另一个同类型对象),可以用std::decay_t去掉decltype(var_impl)的引用和const限定,还原为原始类型:

std::visit([&](const auto & var_impl) {
    using ValueType = std::decay_t<decltype(var_impl)>;
    auto w = std::get<ValueType>(a.var);
    std::cout << w << std::endl;
}, v);

对你问题的回答

这是预期行为,C++标准要求std::get的模板参数必须是variant中明确声明的备选类型之一(或对应的索引)。你不需要在std::visit的lambda里再次获取variant的值——std::visit的核心作用就是自动帮你把当前variant存储的具体类型对象传递给访问器,直接使用这个参数即可,完全没必要再调用std::get。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 23:32:04