我不是專家,但我認爲你不能用fusion::for_each
來實現你想要的。可以工作的一個非常簡單的替代方法是使用fusion::joint_view
將mpl::vector
與您的結構(您的結構適應的序列)連接起來。這個聯合視圖不能直接在boost::make_variant_over
中使用,但這可以通過使用fusion::result_of::as_vector
獲得具有相同元素的fusion::vector
來輕鬆解決。這種方法的一個問題(我不確定它確實是一個問題,但它無疑是醜陋的)是,如果你的向量和你的結構之間有共同的元素,那麼結果變體將在它的列表中有兩次這些元素類型。如果你想解決這個問題,你可以使用mpl::set
而不是你的矢量,然後使用mpl::fold<A, mpl::set<your types...>, mpl::insert<_1,_2> >::type
。這給你一個mpl::set
沒有任何重複的類型。您需要再次使用fusion::result_of::as_vector
才能使用make_variant_over
。
Running on Coliru
#include <iostream>
#include <string>
#include <boost/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/mpl.hpp> //important: allows compatibility fusion-mpl
#include <boost/fusion/include/joint_view.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/set.hpp>
#include <boost/fusion/include/fold.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/insert.hpp>
namespace fusion=boost::fusion;
namespace mpl=boost::mpl;
struct A
{
int a1;
double a2;
float a3;
};
BOOST_FUSION_ADAPT_STRUCT(
A,
(int,a1)
(double,a2)
(float,a3)
)
struct printer
{
template <typename T>
void operator()(T) const
{
std::cout << typeid(T).name() << ";";
}
};
int main()
{
typedef fusion::result_of::as_vector<fusion::joint_view<mpl::vector<bool,std::string>,A> >::type types1;
typedef boost::make_variant_over<types1>::type variant1;
variant1 a = 3.5f;
variant1 b = true;
std::cout << a << " " << b << ". " << fusion::result_of::size<variant1::types>::type::value << " elements in the variant" << std::endl;
fusion::for_each(variant1::types(),printer());
std::cout << std::endl;
typedef mpl::fold<A,mpl::set<std::string,int>,mpl::insert<mpl::_1,mpl::_2>>::type types2;
typedef boost::make_variant_over<fusion::result_of::as_vector<types2>::type>::type variant2;
variant2 a2 = 4;
variant2 b2 = "bla";
std::cout << a2 << " " << b2 << ". " << fusion::result_of::size<variant2::types>::type::value << " elements in the variant" << std::endl;
fusion::for_each(variant2::types(),printer());
std::cout << std::endl;
}
謝謝你的建議。這樣可行! – surfcode
順便說一句,如果我有像A,A1,A2這樣的多個類,是否可以「摺疊」上面的類型信息類型2,而不用重新輸入typedef?例如: 'typedef mpl :: fold ,mpl :: insert> :: type types2;'> :: type types3;' boost :: make_variant_over :: type> :: type variant2; –
surfcode
' typedef mpl :: fold
抱歉編輯,我的意思是: 'typedef mpl :: fold ,mpl :: insert <...>> :: type type1; typedef mpl :: fold> :: type type2; typedef mpl :: fold > :: type type3; boost :: make_variant_over <... :: type> :: type variant; –
surfcode