【发布时间】:2017-06-29 04:51:20
【问题描述】:
使用= 不起作用。
我有这样的代码,但它“有点”难看。
#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++ 是否缺乏支持。
【问题讨论】:
-
您的问题是什么?您是否发布了工作代码?堆栈溢出不适用于代码审查。您是否想要一个“更漂亮”的版本?如果有,你认为哪一部分不好?
-
如果您将您的代码与
std代码的大部分进行比较,那么它并没有那么糟糕。实现这些东西的想法是将丑陋的东西放到一个头文件中,然后你可以忘记它并编写使用它的漂亮代码。 -
visit([&](auto &&v) { dest = v; }, source);。如果源中有没有在dest中的类型,可以使用visit([&](auto &&v) { if constexpr(is_assignable_v<decltype(dest), decltype(v)>) dest = v; else throw "unsupported"; }, source) -
@JohannesSchaub-litb +1,喜欢这个解决方案。我正在为同一件事写一个更复杂的版本,并意识到你的要好得多
-
@JohannesSchaub-litb 为什么不将其转换为答案?已经很完整了
标签: c++ c++17 boost-variant