2013-07-15 64 views
1

我試圖寫一個簡單的「跳過迭代器」與元素的數量模板參數跳過:推導除一個模板參數以外的所有參數?

template <typename T, typename Iter, int Skip> 
class SkipIterator 
{ 
public: 
    SkipIterator(Iter baseIter) : 
     baseIter_(baseIter) 
    { 
    } 

    void operator++() 
    { 
     baseIter_ += Skip; 
    } 

    T &operator*() 
    { 
     return *baseIter_; 
    } 

private: 
    Iter baseIter_; 
}; 

我希望能夠推導基礎IterT類型像這樣:

std::vector<double> dataFromSomewhere; 
SkipIterator<3> skipper(dataFromSomewhere.begin()) 

但編譯器(VS2010)給出了「太少的模板參數」錯誤。

有沒有辦法做到這一點?

+1

不能推導出模板類的模板參數,所以你必須指定反正所有三個。你可以用'make_skip_iterator'函數來解決這個問題,該函數可以推導出'T'和'Iter'。 – chris

+0

請考慮如何實現'end()',這並不是那麼容易,但非常重要。 –

回答

7

你可以提供一個輔助函數:

#include <iterator> 

template <int Skip, typename Iter> 
SkipIterator<typename std::iterator_traits<Iter>::value_type, Iter, Skip> 
    make_skip_iterator(Iter it) 
{ 
    return SkipIterator< 
     typename std::iterator_traits<Iter>::value_type, Iter, Skip 
     >(it); 
} 

,你會用這樣的方式:

​​

這裏是一個live example

注意,那上面的輔助函數的C++ 14的版本會更好看(至少在簽名)由於返回類型推演:

template <int Skip, typename Iter> 
auto make_skip_iterator(Iter it) 
{ 
    return SkipIterator< 
     typename std::iterator_traits<Iter>::value_type, Iter, Skip 
     >(it); 
} 

,當然還有live example

+0

這個答案真的很有用,但我接受了伊戈爾的,因爲他需要更多的XP :) – japreiss

+0

@japreiss現在它應該如何工作。 –

+0

@japreiss:我接受更好的答案時沒有任何問題,只要你這樣做,因爲你認爲它更好。但答案應該被接受,提出或者低估,而不是基於誰在寫他們(好人?討厭的人?低重新興趣的用戶vs高普通常人?)等等,但是基於他們內容。但除此之外,我沒有任何問題與您的選擇:) –

4

模板參數推導只發生在模板函數調用中,從來沒有在涉及類模板名稱的變量聲明中發生。另外,如果你想推導出一些參數,但不是所有的參數,你想要推斷的參數必須在最後。

總而言之,您正在尋找這樣的事情:

template <int Skip, typename Iter> 
auto make_skipper(Iter it)->SkptIterator<decltype(*it), Iter, Skip> { 
    return SkptIterator<decltype(*it), Iter, Skip>(it); 
} 

auto skipper = make_skipper<3>(dataFromSomewhere.begin());