Действительно, вы хотите переместить InputIterator для использования с вставкой OutputIterator. Поскольку этого нет в C ++ 03, должен существовать альтернативный способ указать, что желательно «мелкое» перемещение, а не «глубокое» копирование.
Простой флаг состояния в самом объекте не будет работать, потому что реализация позволяет копировать объект случайным образом, прежде чем фактически поместить его в контейнер. (Ради оптимизации вы знаете, что этого не произойдет, но не стоит беспокоиться об отладочных сборках.)
С моей головы это звучит как работа для пользовательского распределителя. Копируемые конструкции распределителя по умолчанию с использованием размещения new; Вы можете определить альтернативный конструктор и вызвать его, используя вместо этого размещение new.
template< typename T >
struct move_traits {
typedef T must_copy_type; // does not exist in specializations
};
template< typename T >
struct move_if_possible_allocator
: std::allocator< T > {
typedef move_traits<T> traits;
// SFINAE selects this function if there is a specialization
void construct( typename traits::may_move_type *obj, T &value ) {
new( obj ) T(); // default construct
traits::move_obj( *obj, value ); // custom routine
}
// SFINAE selects this function if traits is the base template
void construct( typename traits::must_copy_type *obj, T const &value ) {
new( obj ) T( value ); // copy construct (fallback case)
}
// define rebind... exercise for the reader ;v)
};
template<>
struct move_traits< BlitSurface > {
typedef T may_move_type; // signal existence of specialization
static void move_obj( BlitSurface &out, BlitSurface &in ) {
// fill out and clear in
}
}
Конечно, прекрасно добавить состояние в BlitSurface к отключить перемещение на move_obj
, если некоторые объекты фактически скопированы в контейнер.