2017-06-14 61 views
9

我需要構建n個類型的元組。這n個類型是n個其他類型的值類型。考慮這個片斷:如何從參數包中定義值類型的元組

#include <boost/hana.hpp> 

namespace hana = boost::hana; 

template<class... Types> 
class CartesianProduct 
{ 
public: 
    CartesianProduct(Types... args) : sets(args...) {} 

    hana::tuple<Types...> sets; 
    hana::tuple<Types...::value_type> combination; // does not work obviously... but wo can this be done? 
}; 

的這個應用程序的目的是,像這樣:我通過這個類可能是不同類型的容器的參數包。這個類將這些容器放入一個元組sets。該類還有一個字段combination,它是容器傳遞給該類的許多元素的元組。但是元素的類型是不同容器的值類型。

然後,該類將懶散地構建傳遞給它的容器的笛卡爾積,並將當前組合存儲在combination中。但是我怎樣才能真正以可變的方式獲得容器的值類型?

+0

是否所有類型都有'value_type'? – StoryTeller

+0

嗯,我把這作爲一個先決條件。 –

+0

如果你確實寫了這個懶惰的笛卡爾產品類,那麼如果你能將它貢獻給Hana,那將是非常棒的。我期待添加懶惰的視圖,並且它本身可以懶惰地實現'cartesian_product'是一個好主意。 –

回答

11

當然可以做到。你只需要適當地聲明包擴展。

hane::tuple<typename Types::value_type...> combination; 

注意需要使用typename說明符。經驗法則是將包名稱視爲單一類型。應用相同的語法/語義約束,因爲我們必須指定我們使用範圍解析運算符訪問類型。然後在最後加上包裝擴展。

Live Example

#include <vector> 
#include <map> 
#include <tuple> 

template<class... Types> 
class CartesianProduct 
{ 
public: 
    CartesianProduct(Types... args) : sets(args...) {} 

    std::tuple<Types...> sets; 
    std::tuple<typename Types::value_type...> combination; 
}; 


int main() { 
    std::vector<int> i; 
    std::map<int, std::vector<int>> m; 

    CartesianProduct<std::vector<int>, std::map<int, std::vector<int>>> 
     c(i, m); 

    return 0; 
} 
5

上的說書人的正確答案擴展(接受他的答案,請):

我覺得它更容易通過翻譯薈萃的條款執行這些可視化類型的翻譯是這樣功能,例如:

#include <vector> 
#include <map> 
#include <tuple> 

namespace metafunction_impl 
{ 
    // meta function taking one type (T) and 'returning' one type. 
    // i.e. a unary metafunction 
    template<class T> struct get_value_type 
    { 
    using result = typename T::value_type; 
    }; 
} 

// provide clean interface to the metafunction 
template<class T> using GetValueType = typename metafunction_impl::get_value_type<T>::result; 

template<class... Types> 
class CartesianProduct 
{ 
public: 
    CartesianProduct(Types... args) : sets(args...) {} 

    std::tuple<Types...> sets; 

    // use my metafunction 
    std::tuple<GetValueType<Types>...> combination; 
}; 


int main() { 
    std::vector<int> i; 
    std::map<int, std::vector<int>> m; 

    CartesianProduct<std::vector<int>, std::map<int, std::vector<int>>> 
     c(i, m); 

    return 0; 
} 
+0

這就是爲什麼人們應該將這個包想象爲一個單一類型名稱的可視化。比我的經驗法則更好。 +1 – StoryTeller

相關問題