在 std::tuple 上使用 std::variant 的问题
Problems with using std::variant on std::tuple
我想使用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 上,编译器错误:
未找到
匹配的重载函数 C2783:"声明":无法推断"标识符"的模板参数
我想处理同一类型的一对。我做错了什么?我想不同类型的对会匹配auto const& arg
,所以所有对都应该正确匹配。
这不是指定std::visit
的方式:
template <class Visitor, class... Variants>
constexpr /*see below*/ visit(Visitor&& vis, Variants&&... vars);
它需要一个variant
秒的参数包。不需要tuple
它们,即使它们是非常相似的东西。当你visit
多个variant
时,你的函数调用是用多个参数调用的 - 而不是其中的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
并重新打包元素:
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);
}
正确的引用处理和转发留作练习。
相关文章:
- 在template中使用std::variant的template函数
- 为 std::variant 提供一个运算符 ==
- 如何使用 std::variant 打印地图键/值?
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 在 std::tuple 上使用 std::variant 的问题
- 如何访问存储在 std::variant 中的类的方法
- 更改其类型后,丢失对 std::variant 对象的引用
- std::visit and std::variant usage
- std::variant vs指向C++中异构容器基类的指针
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- 有没有办法避免为 std::variant 类成员中的所有类型编写构造函数?
- 按索引设置 std::variant 的值
- 在 std::variant 中按类型获取索引
- 与传统的多态处理相比,使用 std::variant 有什么优势?
- 无法引用该函数" std:: variant <_Types...> operator =",因为此函数已被删除
- 是否可以使用 std::variant of std::variants
- 如何在给定 std::variant 的情况下检索模板参数包?
- 在构造函数初始化列表中使用 std::variant
- 将 std::variant 与 gmock 1.8 对象一起使用时编译错误
- C++获取std::variant当前帮助的类型的std::typeindex