分配变体< A,B,C>.来自变体< C,B&gt ;? [英] Assign variant<A,B,C> from variant<C,B>?

查看:57
本文介绍了分配变体< A,B,C>.来自变体< C,B&gt ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 = 不起作用.

我有这样的代码,但是有点丑陋".

I have code like this, but it is a "bit" ugly.

#include <iostream>
#include <cassert>
#include <variant>
#include <string>

using namespace std;

namespace detail {
    template<typename... L, typename... R>
    void VariantAssignRec(variant<L...>* lhs, const variant<R...>&rhs, size_t rhs_idx, std::integral_constant<int, -1>) {
    }

    template<typename... L, typename... R, int get_idx>
    void VariantAssignRec(variant<L...>* lhs, const variant<R...>&rhs, size_t rhs_idx, std::integral_constant<int, get_idx> = {}) {
        assert(rhs_idx < std::variant_size_v< variant<R...>>);
        if (get_idx == rhs_idx) {
            cout << "assigning from idx " << get_idx << endl;
            *lhs = std::get<get_idx>(rhs);
            return;
        }
        else {
            std::integral_constant<int, get_idx - 1> prev_get_idx;
            VariantAssignRec(lhs, rhs, rhs_idx, prev_get_idx);
        }
    }
}
template<typename... L, typename... R>
void VariantAssign(variant<L...>* lhs, const variant<R...>&rhs) {
    detail::VariantAssignRec(lhs, rhs, rhs.index(), std::integral_constant<int, std::variant_size_v<variant<R...>>-1>{});
}


int main()
{
   std::variant<int, char, std::string> va = 'a';
   std::variant<std::string, int> vb = string("abc");
   cout << "va index is  " << va.index() << endl; 
   cout << "vb index is  " << vb.index() << endl; 
   VariantAssign(&va, vb);
   cout << "va index now should be 2, and it is  " << va.index() << endl; 
   vb = 47;
   VariantAssign(&va, vb);
   cout << "va index now should be 0, and it is  " << va.index() << endl; 
}

我使用的是VS,因此没有 if constexpr ,但是我正在寻找通用的C ++ 17解决方案,而与VC ++缺乏支持无关.

I am using VS so no if constexpr but I am looking for general C++17 solution regardless of VC++ lacking support.

推荐答案

只需使用访客:

std::variant<A, B, C> dst = ...;
std::variant<B, C> src = B{};

std::visit([&dst](auto const& src) { dst = src; }, src);

如果 src 中存在无法分配给 dst 的类型,则该类型将无法编译-这可能是所需的行为.

If there is a type in src that isn't assignable to dst, this won't compile - which is probably the desired behavior.

如果您最终不经常使用此模式,则可以将分配器移至其自己的函数中:

If you end up using this pattern semi-often, you could move the assigner into its own function:

template <class T>
auto assignTo(T& dst) {
    return [&dst](auto const& src) { dst = src; };
}

std::visit(assignTo(dst), src);

这篇关于分配变体&lt; A,B,C&gt;.来自变体&lt; C,B&gt ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆