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

当仿函数需多参数时,std::variant与std::visit的正确用法

解决std::visit调用失败的问题

你的代码中std::visit调用失败的核心原因是:C++20及更早版本的std::visit不支持直接传递额外参数给访客对象,而gcc 11.3默认采用C++20标准,因此编译器找不到匹配的std::visit重载。

下面给出两种可行的修复方案:

方案一:将额外参数存入访客结构体

修改Visitor结构体,添加成员变量存储需要传递的额外参数,通过构造函数初始化:

#include <iostream>
#include <variant>
#include <vector>
#include <array>
#include <string>

class SomeClass {
public:
    std::vector<int> foo(const std::string& s, const std::array<float, 3>& d){
        return {};
    }
};

struct Visitor{
    const std::string& s;
    const std::array<float, 3>& a;

    // 构造函数传入额外参数
    Visitor(const std::string& str, const std::array<float,3>& arr) 
        : s(str), a(arr) {}
    
    // operator()仅接收variant的当前值参数
    std::vector<int> operator() (SomeClass& c1) {
        return c1.foo(s, a);        
    }
};

int main() {
    std::variant<SomeClass> variants;
    
    std::string s = "c++";
    std::array<float, 3> a {1, 0, 0};
    
    // 初始化Visitor时传入额外参数
    std::visit(Visitor{s, a}, variants);

    return 0;
}

方案二:使用Lambda捕获额外参数(更简洁)

用Lambda表达式替代自定义Visitor结构体,通过捕获列表获取额外参数,Lambda仅接收variant的当前值:

#include <iostream>
#include <variant>
#include <vector>
#include <array>
#include <string>

class SomeClass {
public:
    std::vector<int> foo(const std::string& s, const std::array<float, 3>& d){
        return {};
    }
};

int main() {
    std::variant<SomeClass> variants;
    
    std::string s = "c++";
    std::array<float, 3> a {1, 0, 0};
    
    std::visit([&](SomeClass& c1) {
        c1.foo(s, a);
    }, variants);

    return 0;
}

可选:启用C++23特性

如果你的场景允许使用C23标准,只需给gcc添加编译选项-std=c++23,即可直接保留你原始代码的参数传递方式(C23扩展了std::visit支持额外参数):

// 编译命令:g++ -std=c++23 your_code.cpp
#include <iostream>
#include <variant>
#include <vector>
#include <array>
#include <string>

class SomeClass {
public:
    std::vector<int> foo(const std::string& s, const std::array<float, 3>& d){
        return {};
    }
};

struct Visitor{
    std::vector<int> operator() (SomeClass& c1, const std::string& s, const std::array<float, 3>& a) {
        return c1.foo(s, a);        
    }
};

int main() {
    std::variant<SomeClass> variants;
    
    std::string s = "c++";
    std::array<float, 3> a {1, 0, 0};
    
    std::visit(Visitor{}, variants, s, a);

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 21:50:38