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

Jam*_*mes 9 c++ boost boost-variant

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

我认为这一定是可能的,不知何故,用MPL?

但要澄清一下,索引不是编译时常量表达式.

用例是我需要构造一个变体,稍后将替换为包含正确值的变量,但此时我只知道类型索引.把它想象成一个懒惰的反序列化问题.

pmr*_*pmr 13

您需要使用variant::typestypedef.这为您提供了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;
}
Run Code Online (Sandbox Code Playgroud)

这是运行时变体:

#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;
}
Run Code Online (Sandbox Code Playgroud)

这有点神秘,并且需要使用可变参数进行一些调整才能真正通用,但它可以满足您的需求.其他人需要弄清楚这是否会导致严重的代码爆炸.