c++ - 在 std::tuple 上使用 std::variant 的问题
问题描述
我想std::variant
用来处理变体类型,但遇到了一些问题。
#include <string>
#include <vector>
#include <tuple>
#include <variant>
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...)->overloaded<Ts...>;
void test_variant()
{
using A = int;
using B = double;
using C = std::string;
using var_t = std::variant<A, B, C>;
using var_pair_t = std::tuple<var_t, var_t>;
std::vector<var_pair_t> vec;
for (var_pair_t const& var_pair : vec)
std::visit(overloaded{
[](std::tuple<A, A> const& pair_A) {},
[](std::tuple<B, B> const& pair_B) {},
[](std::tuple<C, C> const& pair_C) {},
[](auto const& arg) {},
}, var_pair);
}
在 GCC 上:https
:
//gcc.godbolt.org/z/p1ljQv 在 VS2017 上编译器错误:
C2672:“函数”:找不到匹配的重载函数
C2783:“声明”:无法推断“标识符”的模板参数
我想处理相同类型的对。我做错了什么?我想不同类型的对会匹配auto const& arg
,所以所有对都应该正确匹配。
解决方案
这不是std::visit
指定的方式:
template <class Visitor, class... Variants>
constexpr /*see below*/ visit(Visitor&& vis, Variants&&... vars);
它需要一个参数包variant
s。它不需要tuple
它们中的任何一个,即使它们是非常相似的东西。当您使用visit
多个variant
s 时,您的函数调用会使用多个参数调用 - 而不是其中的一个tuple
。
要使用标准机器,您需要:
std::visit(overloaded{
[](A const&, A const&) {}, // <== unpack all of these
[](B const&, B const&) {},
[](C const&, C const&) {},
[](auto const&, auto const&) {},
}, std::get<0>(var_pair), std::get<1>(var_pair)); // <== unpack this too
如果您更喜欢在tuple
s 中工作,您可以编写自己的版本visit
来解包variant
s 并重新打包元素:
template <typename F, typename Tuple>
decltype(auto) visit_tuple(F f, Tuple t) {
return std::apply([=](auto... vs){ // <== unpack the variants
return std::visit([=](auto... elems){
return f(std::tuple(elems...)); // <== repack the alternatives
}, vs...);
}, t);
}
适当的参考处理和转发留作练习。
推荐阅读
- python - Python - 将 SEGY 转换为图像/数字列表,标记视野,转换为 SEGY
- node.js - 在 docker 下使用 mongo 表达 API,查询问题
- python - 从Python网格上的纬度/经度给定数据点查找网格上最近的站点索引
- python - ModuleNotFoundError:没有名为“gamingispassion/settings.production”的模块 PYTHONANYWHERE
- php - 使用 PHP 和 cURL 通过 HTTPS 身份验证发布 XML
- javascript - Plunker 正在显示 html 的预览,但不是我的 JavaScript
- android - 如何在 android App 中使用深度链接(打开我的应用程序)实现 Facebook 分享,然后深度链接该帖子?
- swift - UIStackView 伸展子视图对齐它
- python - AttributeError:“dict”对象没有属性“decode”
- xamarin.android - 在 Azure Devops 中为 Android Xamarin ARM 构建