初始化 boost::fusion::map 个值
Initialize boost::fusion::map values
我有一个 boost::fusion::map
这样的:
struct bar {};
struct baz {};
template<typename... Args>
struct foo
{
foo(bar &, baz &) {}
};
template<typename... T>
using MapEntry = boost::fusion::pair<boost::mpl::set<T...>, foo<T...>>;
using Map = boost::fusion::map<
MapEntry<int, bool, double>,
MapEntry<std::string>,
MapEntry<int64_t, uint32_t>,
MapEntry<char, uint64_t>
// ...
>;
然后需要初始化 Map
的实例,将 bar_
和 baz_
传递给所有 foo
构造函数。
目前,我有:
int main()
{
bar bar_;
baz baz_;
Map map_(
boost::fusion::make_pair<boost::mpl::set<int, bool, double>>(foo<int, bool, double>(bar_, baz_)),
boost::fusion::make_pair<boost::mpl::set<std::string>>(foo<std::string>(bar_, baz_)),
boost::fusion::make_pair<boost::mpl::set<int64_t, uint32_t>>(foo<int64_t, uint32_t>(bar_, baz_)),
boost::fusion::make_pair<boost::mpl::set<char, uint64_t>>(foo<char, uint64_t>(bar_, baz_))
// ...
);
return 0;
}
但这很多余。是否可以使此代码更清晰?
首先创建一个函数来创建MapEntry
template<typename E, typename... Args>
E make_map_entry(Args &&...args)
{
return boost::fusion::make_pair<E::first_type>(E::second_type(std::forward<Args>(args)...));
}
第二次创建一个函数来创建 Map
,它使用辅助函数展开 make_map_entry
每个条目
template<typename M, std::size_t ...I, typename... Args>
M make_map_impl(std::index_sequence<I...>, Args &&...args)
{
return M(make_map_entry<boost::fusion::result_of::value_at_c<M, I>::type>(std::forward<Args>(args)...)...);
}
template<typename M, typename... Args>
M make_map(Args &&...args)
{
return make_map_impl<M>(std::make_index_sequence<boost::fusion::result_of::size<M>::value> {}, args...);
}
然后我们可以写
int main()
{
bar bar_;
baz baz_;
Map map(make_map<Map>(bar_, baz_));
return 0;
}
您可以使用自定义条目工厂:
struct bound_factory {
bar& bar_;
baz& baz_;
template <typename... T> auto entry() const {
return boost::fusion::make_pair<boost::mpl::set<T...>>(foo<T...>(bar_, baz_));
}
};
然后您可以按如下方式使用:
int main()
{
bar bar_;
baz baz_;
bound_factory f { bar_, baz_ };
Map map_(
f.entry<int, bool, double>(),
f.entry<std::string>(),
f.entry<int64_t, uint32_t>(),
f.entry<char, uint64_t>()
);
}
Clippy Mode
It looks as if you might be creating a Dependency Injection framework. Please be aware of this rather nice library proposal: Boost DI
我有一个 boost::fusion::map
这样的:
struct bar {};
struct baz {};
template<typename... Args>
struct foo
{
foo(bar &, baz &) {}
};
template<typename... T>
using MapEntry = boost::fusion::pair<boost::mpl::set<T...>, foo<T...>>;
using Map = boost::fusion::map<
MapEntry<int, bool, double>,
MapEntry<std::string>,
MapEntry<int64_t, uint32_t>,
MapEntry<char, uint64_t>
// ...
>;
然后需要初始化 Map
的实例,将 bar_
和 baz_
传递给所有 foo
构造函数。
目前,我有:
int main()
{
bar bar_;
baz baz_;
Map map_(
boost::fusion::make_pair<boost::mpl::set<int, bool, double>>(foo<int, bool, double>(bar_, baz_)),
boost::fusion::make_pair<boost::mpl::set<std::string>>(foo<std::string>(bar_, baz_)),
boost::fusion::make_pair<boost::mpl::set<int64_t, uint32_t>>(foo<int64_t, uint32_t>(bar_, baz_)),
boost::fusion::make_pair<boost::mpl::set<char, uint64_t>>(foo<char, uint64_t>(bar_, baz_))
// ...
);
return 0;
}
但这很多余。是否可以使此代码更清晰?
首先创建一个函数来创建MapEntry
template<typename E, typename... Args>
E make_map_entry(Args &&...args)
{
return boost::fusion::make_pair<E::first_type>(E::second_type(std::forward<Args>(args)...));
}
第二次创建一个函数来创建 Map
,它使用辅助函数展开 make_map_entry
每个条目
template<typename M, std::size_t ...I, typename... Args>
M make_map_impl(std::index_sequence<I...>, Args &&...args)
{
return M(make_map_entry<boost::fusion::result_of::value_at_c<M, I>::type>(std::forward<Args>(args)...)...);
}
template<typename M, typename... Args>
M make_map(Args &&...args)
{
return make_map_impl<M>(std::make_index_sequence<boost::fusion::result_of::size<M>::value> {}, args...);
}
然后我们可以写
int main()
{
bar bar_;
baz baz_;
Map map(make_map<Map>(bar_, baz_));
return 0;
}
您可以使用自定义条目工厂:
struct bound_factory {
bar& bar_;
baz& baz_;
template <typename... T> auto entry() const {
return boost::fusion::make_pair<boost::mpl::set<T...>>(foo<T...>(bar_, baz_));
}
};
然后您可以按如下方式使用:
int main()
{
bar bar_;
baz baz_;
bound_factory f { bar_, baz_ };
Map map_(
f.entry<int, bool, double>(),
f.entry<std::string>(),
f.entry<int64_t, uint32_t>(),
f.entry<char, uint64_t>()
);
}
Clippy Mode
It looks as if you might be creating a Dependency Injection framework. Please be aware of this rather nice library proposal: Boost DI