2

これに似たスレッドQ1またはQ2がいくつかありますが、正確ではありません。

問題は、コードの重複なしに、次のコードをエレガントな方法で記述することです。

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 関数と非 const 関数のコードの重複を回避する洗練された方法があります。ただし、const_iterator を 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;
};
4

2 に答える 2

2

どうですか:

class container{
    iterator begin(){
        return iterator(getStuff());
    }

    const_iterator begin() const{
        return const_iterator(getStuff());
    }

    private:
       Stuff getStuff() const  { [some code here] }
};

共通コードがある場合。
その仕事をするプライベートメソッドに移動します。

于 2012-04-30T22:36:48.507 に答える
1

わかりました、明らかにこれが最良の答えです:

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 );
        }
}   
于 2012-05-01T19:53:41.807 に答える