有多種方法可以做到這一點。你不需要全部瞭解它們,只需找到一個具有你想要的功能。
以下是三種完全不同的方法。
擷取音訊從實例爲模板
template<class Src, template<class...>class Dest>
struct transcribe;
template<class Src, template<class...>class Dest>
using transcribe_t=typename transcribe<Src,Dest>::type;
template<template<class...>class Src, class...Ts, template<class...>class Dest>
struct transcribe<Src<Ts...>, Dest>{
using type=Dest<Ts...>;
};
然後:
transcribe_t<decltype(topics), Foo> x;
侵入通過修改富
這也可以侵入通過修改Foo
取束,而不是進行一個揹包。
template <class Bundle>
struct Foo;
template <typename... T>
struct Foo<PossibleTypes<T...>>{
std::tuple<T...> member;
};
或
template <template<class...>class Z, typename... T>
struct Foo<Z<T...>>{
std::tuple<T...> member;
};
則:
Foo<decltype(topics)> x;
它可以是更實際的,如果你不只是在傳遞一組...
參數。
價值爲基礎的元編程
我們也可以處理這個使用基於價值的元編程:
template<class T>
struct tag_t {constexpr tag_t(){} using type=T;};
template<class T>
constexpr tag_t<T> tag{};
template<template<class...>class Z>
struct ztemplate_t {
constexpr ztemplate_t() {}
template<class...Ts> using apply=Z<Ts...>;
template<class...Ts>
constexpr tag_t<Z<Ts...>> operator()(tag_t<Ts>...)const{ return {}; }
};
template<template<class...>class Z>
constexpr ztemplate_t<Z> ztemplate{};
template<class Tag>
using type=typename Tag::type;
template <class... T>
struct PossibleTypes {
template<template<class...>class Z>
constexpr auto operator()(ztemplate_t<Z> z) const {
return z(tag<T>...);
}
};
給我們:
int main(){
type<decltype(topics(ztemplate<Foo>)) > x;
return 0;
}
這是非常漂亮的。 Live example。
tag
將類型提升爲值。 ztemplate
將模板提升爲一個值。
ztemplate<some_template>(tag<T0>, tag<T1>)
返回施加some_template
到T0, T1
像tag_t<some_template<T0, T1>>
的結果的tag
。
要回到標籤的類型,我們做一個type<decltype(some_tag_expression)>
。
我修改了您的PossibleTypes
也有一個operator()(ztemplate)
將模板應用於存儲在PossibleTypes
中的類型。
隨着您進行更多基於類型的操作,這種瘋狂效果會更好,因爲C++中的基於值的編程比模板語法更具表現力且更易於使用。
@mihai以上都不需要實例化對象?在任何情況下,我都會創建該類型。然後,因爲你的代碼做了,我創建了一個類型的實例(證明它工作,我猜)。刪除然後'X',你有一個類型表達式,沒有實例。使用typedef或使用給它一個名字,或其他。 – Yakk
阿爾夫對不起。代碼的另一部分存在問題。很棒! –