2009-10-13 35 views
5

我正在std :: set做一個模板包裝。爲什麼我的Begin()函數聲明出錯?錯誤返回std ::設置<T> ::模板中的迭代器

template <class T> 
class CSafeSet 
{ 
    public: 
     CSafeSet(); 
     ~CSafeSet(); 

     std::set<T>::iterator Begin(); 

    private: 
     std::set<T> _Set; 
}; 

錯誤:類型的std ::集,性病::分配器< _CharT>>「不是從類型 'CSafeSet'

+3

附註:請閱讀關於在標識符中使用下劃線的內容。 http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier/228797#228797 – 2009-10-13 18:39:49

+1

短版本:「不要用下劃線開始標識符名稱「 – jalf 2009-10-13 19:03:46

+0

長版本:後接大寫字母的下劃線保留給編譯器。雙下劃線後面的任何內容都保留給編譯器。 – GManNickG 2009-10-13 22:03:23

回答

17

衍生嘗試typename

template <class T> 
class CSafeSet 
{ 
    public: 
     CSafeSet(); 
     ~CSafeSet(); 

     typename std::set<T>::iterator Begin(); 

    private: 
     std::set<T> _Set; 
}; 

您需要的類型名稱因爲它依賴於模板T.更多信息在代碼上方的鏈接中。這個東西很多的更加容易,如果你使用的typedef的:

template <class T> 
class CSafeSet 
{ 
    public: 
     typedef T value_type; 
     typedef std::set<value_type> container_type; 
     typedef typename container_type::iterator iterator_type; 
     typedef typename container_type::const_iterator const_iterator_type; 

     CSafeSet(); 
     ~CSafeSet(); 

     iterator_type Begin(); 

    private: 
     container_type _Set; 
}; 

在一個側面說明,如果你想完成你需要允許CSafeSet做同樣的事,作爲一個set could,這意味着使用自定義比較和分配器:

template <class T, class Compare = std::less<T>, class Allocator = std::allocator<T> > 
class CSafeSet 
{ 
    public: 
     typedef T value_type; 
     typedef Compare compare_type; 
     typedef Allocator allocator_type; 

     typedef std::set<value_type, compare_type, allocator_type> container_type; 
     typedef typename container_type::iterator iterator_type; 
     typedef typename container_type::const_iterator const_iterator_type; 

     // ... 
} 

和建議的最後一位,如果你要創建一個圍繞類的包裝,儘量遵循相同的命名約定的類來自何處。也就是說,你的Begin()應該可能是begin()(並且我個人認爲C在類名奇怪之前,但是這取決於你:])

+1

注意你的CSafeSet類模板有錯誤。您還需要typename來定義迭代器類型,因爲它們也是依賴的。例子:typedef ** typename ** container_type :: iterator iterator_type;沒有該類型名稱,它不應該在標準的一致性編譯器中編譯。我猜想你在Visual Studio(2008年之前的版本,當我認爲這是固定的)時嘗試過,哪個錯誤接受了沒有typename的行。 – 2009-10-13 18:49:47

+0

我根本沒有嘗試,實際上。感謝您指出這一點,我是愚蠢的(很常見):) – GManNickG 2009-10-13 22:02:17

+0

非常感謝,GMan。 – jackhab 2009-10-14 08:09:35