使用传递的 lambda 调用 std::visit

铁路索引

我有一个包含variant.

我想为该结构编写一个成员函数,该函数应该根据当前持有的类型变体运行代码。

但是,我在编译时遇到了问题。我不想使用更多的“模板恶作剧”,比如使用单独的结构来定义,operator(T&)因为它会更多地污染语法。下面是一个例子:

struct Data {

std::variant<int, double> var;


//Into this function,multiple lambdas should be passed for cases that the user wants to handle
template<typename ... Funcs>
void apply(Funcs&&... funcs) {
    std::visit(std::forward<Funcs>(funcs)...,var);
}
};
int main() {
    Data d;
    d.var = 4;
    //variant holds int and lambda provided that takes int&, execute it:
    d.apply([](int& i){
        std::cout << "I am Int Poggers" << std::endl;
    });
    d.var = 0.0;
    //variant holds double but no lambda passed that takes a double, hence nothing happens:
    d.apply([](int& i){
        std::cout << "I am Int Poggers" << std::endl;
    });
}

我什至不知道编译器想从我这里得到什么:https : //godbolt.org/z/oM4584anf

最大66

您的问题是std::visit()需要一个必须处理每种类型的std::variant.

但是,我在编译时遇到了问题。我不想使用更多的“模板恶作剧”,比如使用单独的结构来定义 operator(T&),因为它会更多地污染语法。

没有什么复杂的。

您可以简单地添加一个简单的结构(带有推导指南)如下(以及在cppreferencestd::visit()页面中提出的

template<class... Ts> struct overloaded : Ts...
 { using Ts::operator()...; };

template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

然后,考虑到您想要std::visit()return void,您可以在您的apply()方法中添加一个通用的 lambda

template<typename ... Funcs>
void apply(Funcs&&... funcs) {
    std::visit(overloaded{ // <-- pass through overloaded
               [](auto const &){}, // <-- and add this generic lambda
               std::forward<Funcs>(funcs)...},var);
}

现在第一个apply()电话

d.apply([](int& i){
    std::cout << "I am Int Poggers" << std::endl;
});

应该编译调用提供的 lambda,因为它是一个更好的匹配(假设d包含int),第二个调用 compile 调用什么都不做的泛型 lambda,因为泛型 lambda 是double.

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

尝试使用std :: visit和lambda表达式从std :: variant返回值

如何在带有访问者的lambda中调用std :: visit,访问者是按值捕获的函数对象

使用 std::bind 和 std::visit

Xcode 10调用不可用函数std :: visit

是否可以在没有lambda的情况下使用std :: visit(只是一个简单的类)?

std :: visit如何与std :: variant一起使用?

我可以在对std :: visit的调用中更改std :: variant中的保留类型

对可变参数模板结构使用std :: visit

如何使用std :: visit将std :: variant的值转换为std :: string

使用lambda表达式和std :: function没有匹配的函数调用错误。

在从std :: variant继承的类上使用std :: visit-libstdc ++与libc ++

如何使用可变参数模板将std :: variant与std :: visit一起进行?

std :: visit无法识别类型

使用std :: map的Miniheap Lambda

std :: functions和lambda函数传递

传递给线程的lambda内的调用函数

了解std :: apply在std :: visit内部

std :: visit和std :: variant用法

std::sort 与 lambda functin 不匹配调用

调用带有std :: function作为lambda参数的函数

如何调用存储在指向std :: function的指针中的lambda?

使用std :: move传递临时lambda,或“拉出”临时参数,有什么区别?

将对象传递给Lambda std :: thread(C ++)中的函数:尝试使用已删除的函数

无法从Lambda捕获将std ::: move移至lambda内部的函数调用,为什么?

无法在使用Kotlin的方法调用中为接口传递lambda(例如setOnClickListener的执行方式)

为什么std :: apply调用lambda但不能调用等效的模板函数?

我可以使用lambda调用将路径参数传递给另一个lambda函数吗?

如何从 std::visit 返回 const&?

如何从 std::visit 返回 const&?