È necessario utilizzare il typedef variant::types
. Questo ti dà una sequenza MPL compatibile che possiamo usare con mpl::at
e un modello per fare le nostre offerte. Questo fa il trucco:
#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;
}
Qui va il runtime-variante:
#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;
}
E 'un po' arcano e avrà bisogno di qualche ritocco con variadic argomenti per essere veramente generica, ma fa quello che vuoi . Qualcun altro ha bisogno di capire se questo si traduce in un significativo blow-up del codice .
Dato che si parla di MPL, penserei che 'N' (l'indice di tipo) sia noto in fase di compilazione, tuttavia la deserializzazione pigra suggerisce che potrebbe essere disponibile solo in fase di esecuzione -> qual è? –
@MatthieuM. Questo sarebbe impossibile con il dopo. Spero per il primo, altrimenti la mia risposta è senza valore. – pmr
@MatthieuM. Ah, buon punto: è disponibile solo in fase di esecuzione. – James