访问者访问变体并返回不同类型时出错

Error with visitor to variant and returning different types

本文关键字:同类型 出错 返回 访问 访问者      更新时间:2023-10-16
#include <iostream>
#include <vector>
#include <variant>
template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>;
class data_output
{
public:
double create_data() { return 1.57;}
};
class data_output_two
{
public:
int create_data() { return 66;}
};

int main()
{
using my_type = std::variant<data_output, data_output_two>;
std::vector<my_type> data_vec;
auto my_lambda = overload{[](data_output& d) {return d.create_data();},
[](data_output_two& d) {return d.create_data();}};
data_vec.emplace_back(data_output{});
data_vec.emplace_back(data_output_two{});
std::cout << std::visit(my_lambda, data_vec[0]) << "n";
}

用这个我得到错误

/usr/include/c++/8.2.1/variant:836:43: error: 
invalid conversion from ‘std::__success_type<int>::type (*)(overload<main()::<lambda(data_output&)>, main()::<lambda(data_output_two&)> >&, std::variant<data_output, data_output_two>&)’ 
{aka ‘int (*)(overload<main()::<lambda(data_output&)>, main()::<lambda(data_output_two&)> >&, std::variant<data_output, data_output_two>&)’}
to ‘double (*)(overload<main()::<lambda(data_output&)>, main()::<lambda(data_output_two&)> >&, std::variant<data_output, data_output_two>&)’ [-fpermissive]
{ return _Array_type{&__visit_invoke}; }

如果我尝试从data_outputdata_output_two返回一个int,它编译得很好。我在这里俯瞰什么?这是一个到godbolt 的链接

编辑:

我想做std::visit(gen_visit, vec[0]),得到一个二重,然后可能做std::visit(get_visit, vec[1]),获得一个int。这可能吗?

Visit返回单个类型。

您的代码要求它返回两种不同的类型。

它不能那样做。

现在,它返回的单个类型可能是两种类型的变体。但这主要是在路上踢罐子。

{[](data_output& d)->std::variant<int,double> {return d.create_data();},
[](data_output_two& d)->std::variant<int, double> {return d.create_data();}};

有了这个,你必须重新访问才能打印:

std::visit( [](auto&&x){std::cout <<  x << "n";}, std::visit(my_lambda, data_vec[0]) );

现在,您可以编写一些元编程来推导composit重载/访问的正确返回类型。

但更实际的是,只需在第一次访问时进行处理:

std::visit([&](auto&&x){ std::cout<<my_lambda(x)<<"n";}, data_vec[0] );