构造一个包含变体类型索引中第 n 个类型的值的 boost 变体?

发布于 2025-01-06 09:38:22 字数 232 浏览 0 评论 0原文

我想构造包含默认构造值的 boost::variant ,并使用类型索引指定 - 而无需在类型索引上编写我自己的 switch 语句。

我想这一定可以通过MPL 实现吗?

但需要澄清的是,索引不是编译时常量表达式。

用例是我需要构造一个变体,稍后将其替换为包含正确值的变体,但此时我只知道类型索引。将其视为惰性反序列化问题。

I want to construct boost::variants containing default-constructed values, specified with a type index - without writing my own switch statement over the type index.

I figure this must be possible, somehow, with MPL?

To clarify though, the index is not a compile-time constant expression.

The use case is that I need to construct a variant which will later be replaced with one containing the correct value, but at this point I only know the type index. Think of it as a lazy deserialisation problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不必了 2025-01-13 09:38:22

您需要使用 variant::types typedef。这为您提供了一个 MPL 兼容序列,然后我们可以将其与 mpl::at 和模板一起使用来进行竞价。这可以解决问题:

#include <string>
#include <boost/variant.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>

template<typename U, typename V>
void construct_in(V& v) {
  v = U();
  // modern
  // v = U{};
}

int main()
{
  typedef boost::variant<int, std::string> variant;
  typedef boost::mpl::at<variant::types, boost::mpl::int_<1>>::type pos;
  variant v;
  // use type deduction
  construct_in<pos>(v);
  // does not throw, does work
  std::string& s =boost::get<std::string>(v);
  return 0;
}

这是运行时变体:

#include <string>
#include <vector>
#include <functional>

#include <boost/variant.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/for_each.hpp>

typedef boost::variant<int, std::string> variant;
typedef variant::types types;
typedef std::vector< std::function<void(variant&)> > fvec;

template<typename U, typename V>
void construct_in(V& v) {
  v = U{};
}

struct build_and_add {
  fvec* funcs;
  template<typename T>
  void operator()(T) {
    funcs->push_back(&construct_in<T, variant>);
  }
};


int main()
{

  variant v;
  std::vector< std::function<void(variant&)> > funcs;

  // cannot use a lambda, would need to be polymorphic
  build_and_add f = {&funcs};
  boost::mpl::for_each<types>(f);

  // this is runtime!
  int i = 1;

  funcs[i](v);
  // does not throw, does work
  std::string& s =boost::get<std::string>(v);
  return 0;
}

它有点神秘,需要使用可变参数进行一些调整
参数确实是通用的,但它可以满足您的要求。其他人需要弄清楚这是否会产生重大影响
代码爆炸。

You need to use the variant::types typedef. This gives you an MPL compatible sequence which we can then use with mpl::at and a template to do our bidding. This does the trick:

#include <string>
#include <boost/variant.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>

template<typename U, typename V>
void construct_in(V& v) {
  v = U();
  // modern
  // v = U{};
}

int main()
{
  typedef boost::variant<int, std::string> variant;
  typedef boost::mpl::at<variant::types, boost::mpl::int_<1>>::type pos;
  variant v;
  // use type deduction
  construct_in<pos>(v);
  // does not throw, does work
  std::string& s =boost::get<std::string>(v);
  return 0;
}

Here goes the runtime-variant:

#include <string>
#include <vector>
#include <functional>

#include <boost/variant.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/for_each.hpp>

typedef boost::variant<int, std::string> variant;
typedef variant::types types;
typedef std::vector< std::function<void(variant&)> > fvec;

template<typename U, typename V>
void construct_in(V& v) {
  v = U{};
}

struct build_and_add {
  fvec* funcs;
  template<typename T>
  void operator()(T) {
    funcs->push_back(&construct_in<T, variant>);
  }
};


int main()
{

  variant v;
  std::vector< std::function<void(variant&)> > funcs;

  // cannot use a lambda, would need to be polymorphic
  build_and_add f = {&funcs};
  boost::mpl::for_each<types>(f);

  // this is runtime!
  int i = 1;

  funcs[i](v);
  // does not throw, does work
  std::string& s =boost::get<std::string>(v);
  return 0;
}

It's a little arcane and will need some tweaking with variadic
arguments to be truly generic, but it does what you want. Someone else needs to figure out if this results in significant
code blow-up.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文