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