您可以隨時自動創建包含原始集合及其容器包裝對象的序列。
爲此,我們需要一個一元的λ:
template <template <typename...> class Container>
struct MakeContainerOfT {
template <typename T>
struct impl {
using type = Container<T>;
};
};
這可以處理不同的地圖(他們需要一個數值型)和數組每個集裝箱(有一個非類型模板參數)。作爲獎勵,這裏是工廠,使大小N
的數組:
template <std::size_t N>
struct ArrayOfT {
template <typename T>
struct impl {
using type = std::array<T, N>;
};
};
現在,我們需要對我們的一套適用本拉姆達(或任何其它一元拉姆達)爲我們給出任何容器的設施。
template <typename Sequence, template <typename> class Transform>
struct TransformedSequenceBuilder {
using type = typename boost::mpl::reverse_fold<Sequence,
boost::mpl::set0<>,
boost::mpl::insert<boost::mpl::_1,
Transform<boost::mpl::_2>>>::type;
};
我們可以用「蓄壓器」,將執行此轉化lambda表達式的可變參數序列終於着手:
template <typename Sequence, template <typename> class... Transforms>
struct MakeFullSequence;
template <typename Sequence, template <typename> class Transform, template <typename> class... Tail>
struct MakeFullSequence<Sequence, Transform, Tail...> {
using type = typename boost::mpl::reverse_fold<typename MakeFullSequence<Sequence, Tail...>::type,
typename TransformedSequenceBuilder<Sequence, Transform>::type,
boost::mpl::insert<boost::mpl::_1, boost::mpl::_2>>::type;
};
template <typename Sequence>
struct MakeFullSequence<Sequence> {
typedef Sequence type;
};
的最後一步是定義一個別名爲您感興趣的容器:
template <typename Sequence>
using wrapped_set = typename MakeFullSequence<Sequence,
ContainerOfT<std::vector>::template impl,
ContainerOfT<std::set>::template impl//,
/* any transformation you fancy here */>::type;
爲了測試這一點,我們可以執行一個平等的測試:
using le_set = boost::mpl::set<int, double, char>;
using le_vector_set = boost::mpl::set<std::vector<int>, std::vector<double>, std::vector<char>>;
using le_set_set = boost::mpl::set<std::set<int>, std::set<double>, std::set<char>>;
using le_transformed_set = wrapped_set<le_set>;
using le_manually_transformed_set = boost::mpl::joint_view<boost::mpl::joint_view<le_set, le_set_set>::type, le_vector_set>::type;
std::cout << boost::mpl::equal<le_transformed_set,
le_manually_transformed_set>::value;
用法則非常簡單:用戶只需要提供「原始」類型集合Set
每個需要它的時候,你分支的邏輯到wrapped_set<Set>
:
class Foo
{
typedef boost::mpl::set<bool, int, double> allowedTypes;
template<class T>
void some_templated_method()
{
BOOST_MPL_ASSERT((boost::mpl::has_key<wrapped_set<allowedTypes>, T>));
}
};
你可以找到演示說明我們做最後的原始集合,矢量包裝集合和集合包裝集合在這裏:Live Demo
通過該設計,您還可以添加任何其他「重複風味」,你喜歡。引用(對應const
)對應的輸入類型?只需通過std::add_lvalue_reference
(即std::add_const
)即可!
我只是讓你知道我編輯我的答案有點讓類型轉換更通用。核心思想仍然是一致的,但是如果你需要,它可以讓你更靈活:) – Rerito