2010-07-08 33 views
3

再次,我希望C++具有較強typedef S:在這種情況下如何使模板類型推斷工作?

#include <vector> 

template<typename T> 
struct A { 
    typedef std::vector<T> List; 
}; 

template<typename T> 
void processList(typename A<T>::List list) { 
    // ... 
} 

int main() { 
    A<int>::List list; 
    processList<int>(list); // This works. 
    processList(list);  // This doesn't. 
} 

顯然,編譯器看到list作爲std::vector<int>而不是A<int>::List,所以它不能匹配它是預計A<T>::List

在實際的情況下,它是一個較長的類型名稱,經常重複,這是一個滋擾。除了讓processList代替接受vector,有什麼辦法可以爲我做模板類型推斷嗎?

回答

5

有沒有什麼辦法可以讓我的模板類型推斷工作?

不,這就是所謂的不可扣除的上下文

但是,爲什麼你還需要這個?各地通過序列的慣用方式是通過迭代器:

template<typename It> 
void processList(It begin, It end) { 
    typedef typename std::iterator_traits<It>::value_type T; 
    // .... 
} 

int main() { 
    A<int>::List list; 
    processList(list.begin(), list.end()); // works now 
    return 0; 
} 

(請注意,在你的問題,你傳遞一個vector按值,這是一個壞的事情對於迭代器,這是罰款和甚至是首選)

但是,如果你真的絕望了,你可以具備的功能演繹的任何容器取一定數量的模板參數:

template<typename T, typename A, template<typename,typename> C> 
void processList(C<T,A>& cont) { 
    // .... 
} 

但是請注意,這將匹配任何帶有兩個模板參數的模板。 OTOH,它不會匹配像std::map這樣的容器,它具有不同數量的參數。

+0

嗯,好點。我想我不會太在意「慣用」,因爲這只是在一個班級內部使用。通過一個(在這個簡單的例子中我忽略的引用......)這個東西本身使得在調用站點的代碼更短。 – Thomas 2010-07-08 09:48:20

+0

爲了簡化示例,我通過值傳遞了向量。實際上,我傳遞一個const引用,當然。你的更新很整潔;不是我會用它(我不是那麼絕望),但記住它是很好的。 – Thomas 2010-07-08 10:10:56

+1

+1,但要小心(用於編輯)標準容器沒有固定數量的參數 - 它是實現定義的,實現只需提供模板的任何額外參數的默認值,以便假定簽名的實例化目前在標準編譯。 – 2010-07-08 11:39:43

0

明白了。用繼承來創建一個類型,實際上是不同的:

template<typename T> 
class A : public std::vector<T> { 
}; 

好東西我不需要在這種情況下,非默認的構造函數。

+0

好的解決方案 - 不知道爲什麼你被拒絕投票 – Elemental 2010-07-08 11:27:33

+0

因爲它很可怕:'std :: vector'沒有虛擬析構函數。 – 2010-07-08 11:33:16

+0

那麼他可能不會通過基類指針多態地使用它,所以它可能不是一個問題。托馬斯,也許你可以發佈最終代碼,以便我們看看它是否會造成其他問題。 – n1ckp 2010-07-08 12:15:02

0

。在你的情況下,一個簡單的解決方案:

template <class C> 
void processList(C const& list) 
{ 
    typedef typename C::value_type value_type; 
    BOOST_STATIC_ASSERT_MSG((boost::same_type< C, typename A<value_type>::List >), 
    NOT_A_A_LIST_TYPE, 
    (C, A<value_type>) 
); 
    // do your stuff 
} 

注意的C++ 0x來了!

template <typename second> 
using TypedefName = SomeType<OtherType, second, 5>; 

我不知道這會工作

template <typename value> 
using AList = typename A<value>::List; 
相關問題