2009-06-11 123 views
2

好的,所以我寫了一個類似於stl的算法,稱爲cartesian_product。對於那些不知道的人來說,笛卡爾積是兩組中每對可能的元素。所以{1, 2, 3}{10, 20, 30}笛卡爾乘積是幫助使用C++模板模板

{(1,10), (1,20), (1,30), (2,10), (2,20), (2,30), (3,10), (3,20), (3,30)}

所以函數看起來像

template <typename InIt1, typename InIt2, typename OutIt> 
void 
cartesian_product(InIt1 first1, InIt1 last1, InIt2 first2, InIt2 last2, OutIt out) 
{ 
    for (; first1 != last1; ++first1) 
     for (InIt2 it = first2; it != last2; ++it) 
      *out++ = std::make_pair(*first1, *it); 
} 

有沒有模板類型定義,所以我做了一個traits類來保存類型 的輸出迭代器是:

template <typename ObjA, typename ObjB, template <typename> class Container> 
struct cartesian_product_traits 
{ 
    typedef Container<std::pair<ObjA, ObjB> > type; 
}; 

那麼我可以說:

typedef cartesian_product_traits<int, int, std::vector>::type IntPairList; 
IntPairList my_list; 
cartesian_product(v1.begin(), v1.end(), 
        v2.begin(), v2.end(), 
        std::back_inserter(my_list); 

但這似乎並沒有編譯。我得到一個不錯的錯誤:

error C3201: the template parameter list for class template 'std::vector' does not match the template parameter list for template parameter 'Container' 

所以我很難過。我如何得到這個工作?

回答

8

矢量模板參數列表不只是一個元素,它有兩個:

template < class T, class Allocator = allocator<T> > class vector 

所以爲了接受向量,就需要有一個模板的模板參數有兩個空格:

template <typename ObjA, typename ObjB, template <typename, typename> class Container> 
struct cartesian_product_traits 

編輯:削減了一些建議,誤解你的代碼。

這樣做正確辦法是使用一個可變參數宏的模板的模板參數的方式:

template <typename ObjA, typename ObjB, template <typename ...> class Container> 
struct cartesian_product_traits 

但是,這遠不是一個標準。如果是我的代碼,我可能只是有消費者砸向了完整的模板:

std::vector< std::pair<int, int> > 

短於

cartesian_product_traits<int, int, vector> 

,而後者只會有助於如果定義爲笛卡爾積改變。

2

std::vector的模板實際上相當複雜(帶有可選的分配器模板參數& c) - 而stdlib中的其他容器也不是那麼簡單。在你的鞋子裏,我會將cartesian_product_traits的第三個參數變成一個普通的typename PairsContainer,並且依賴於調用者去將它作爲合適的容器對傳遞的小麻煩。

+0

+1投票僅僅表示「&c」代表「等」。 – rlbond 2009-06-11 05:33:00