Ответ 1
Собственно, у меня была аналогичная проблема в проекте, это решение, с которым я столкнулся:
#include <iterator>
#include <type_traits>
/** \brief Provides an interface to random accessible ranges
* \tparam RAIterator must be a random access iterator
*
* This class doesn't allocate any memory by itself and
* provides only an interface into the data of another
* container.
* \attention Keep in mind that although all methods are
* \c const, the returned RAIterator might not be a \c const_iterator
* at all. It is your responsibility to make sure that
* you don't invalidate the given range while working on it.
**/
template <class RAIterator>
class Slice
{
public:
//! Typedef for convenience when working with standard algorithms
typedef RAIterator iterator;
//! Alias to the iterator reference type
typedef typename std::iterator_traits<RAIterator>::reference reference;
//! Creates the slice.
//! \param first, last a valid range
Slice(RAIterator first, RAIterator last) : first(first), last(last){}
//! Creates the slice.
//! \param first iterator to the first element
//! \param length of the range [first, first+length)
//! \remark if length is negative, an empty slice is assumed.
Slice(RAIterator first, int length) :
first(first),
last( length > 0 ? first + length : first)
{}
//! The default constructor is deleted, as it would resemble an empty slice
Slice() = delete;
///@{
//! \brief Defaulted construcors.
Slice(const Slice&) = default;
Slice(Slice&&) = default;
Slice& operator=(const Slice&)= default;
Slice& operator=(Slice&&)= default;
/**@}*/
//! Returns an iterator to the begin of the range
RAIterator begin() const{ return first; }
//! Returns an iterator to the end of the range
RAIterator end() const{ return last; }
//! Returns the size of the slice.
typename std::iterator_traits<RAIterator>::difference_type size() const{
return std::distance(first, last);
}
//! Provides random access for the values interfaced by Slice
reference operator[](size_t index) const { return first[index]; }
private:
RAIterator first; //!< begin of the range
RAIterator last; //!< end of the range
};
/** \brief Creates a slice from the given range
* \tparam RAIterator should be an random access iterator
* \returns a slice [first,last)
* \param first, last is the range
**/
template <class RAIterator>
Slice<RAIterator> make_slice(RAIterator first, RAIterator last){
return Slice<RAIterator>(first, last);
}
Теперь вы можете использовать Slice
так же, как в вашем примере:
std::vector< double > B({1,2,3,4,5});
Slice A(B.begin() + 2, B.size() - 2);
A[0] = 5;
// B == {1,2,5,4,5}
EDIT. Если вы хотите более зрелый фрагмент, используйте boost::adaptors::slice
, если это возможно.