有幾個類似的線程Q1或Q2到這個,但不完全。爲通用容器中的begin()和end()函數避免重複的代碼
的問題是簡單地寫在一個優雅的方式將以下代碼,而無需重複代碼:
template <typename T, class Container = std::vector<T> >
class container{
iterator begin(){
return iterator(data_.begin(), 1);
}
const_iterator begin() const{
return const_iterator(data_.begin(), 1);
}
Container data_;
};
Q2有一種優雅的方式來避免const和non-const函數的代碼複製具有完全相同的簽名。但是,這不是這種情況,因爲沒有強制將const_iterator轉換爲迭代器。
Q1提供了一個使用模板的好方法,但是,一旦容器是一個類,begin_impl
函數變爲static
並且同時變成friend
。
最優雅的代碼我想出是:
template <T>
class container{
template< typename I, typename C >
static I begin_impl(C & c){
return I(data_.begin(), 1);
}
template< typename I, typename C >
friend I container<T>::begin_impl(C & c);
iterator begin(){
return container<T>::template begin_impl<iterator>(*this);
}
const_iterator begin() const{
return container<T>::template begin_impl<const_iterator>(*this);
}
}
我的問題是,這是否是您認爲最優雅的方式。如果不是,請提供一些更好的代碼。
編輯:我的迭代器實現:
class container{
template <bool isConst>
class iterator_ {
public:
typedef Container container_type;
typedef typename Container::value_type value_type;
typedef typename Container::difference_type difference_type;
typedef typename Container::size_type size_type;
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef typename Container::pointer pointer;
typedef typename Container::const_pointer const_pointer;
typedef typename std::forward_iterator_tag iterator_category;
template<bool isCond, typename cref, typename ref>
struct IS_CONST_REF{
typedef ref reference_type;
};
template<typename cref, typename ref>
struct IS_CONST_REF<true, cref, ref>{
typedef cref reference_type;
};
typedef typename IS_CONST_REF<isConst, const_reference, reference>::reference_type ref;
template<bool isCond, typename citr, typename itr>
struct IS_CONST_ITR{
typedef itr iterator_type;
};
template<typename citr, typename itr>
struct IS_CONST_ITR<true, citr, itr>{
typedef citr iterator_type;
};
typedef typename IS_CONST_ITR<isConst, typename Container::const_iterator, typename Container::iterator>::iterator_type itr;
iterator_()
:data_(), stepSize_(0){
}
iterator_(itr data, difference_type stepSize)
:data_(data), stepSize_(stepSize){
}
iterator_(const iterator_<false>& src)
:data_(src.getData()), stepSize_(src.getStepSize()){
}
[some more code ...]
protected:
itr data_;
difference_type stepSize_;
};
typedef iterator_<true> const_iterator;
typedef iterator_<false> iterator;
};
那豈不是更容易使'const_iterator'私下兌換成'iterator',並在常量方面實現非const'begin' 'begin'? – ildjarn
它不是構成嚴重的安全漏洞? – guinny
如果轉換函數沒有公開訪問的話,那就不行了...... – ildjarn