C++ 如何避免使用插入迭代器调用复制构造函数 模板 void BlitSurface::提取帧(输出它, 整数帧宽度,整数帧高度, 每行整数帧,每列整数帧, 布尔填充)常数 { SDL_表面**temp_surf=SDL_Ex_ExtractFrames(_表面、框架宽度、框架高度、每行框架、每列框架、填充); int surface_count=每行帧数*每列帧数; 对于(int i=0;i
,提到正在调用一个复制构造函数。在提供的示例中,容器似乎被定义为保存BlitSurface。类似于std::vectorC++ 如何避免使用插入迭代器调用复制构造函数 模板 void BlitSurface::提取帧(输出它, 整数帧宽度,整数帧高度, 每行整数帧,每列整数帧, 布尔填充)常数 { SDL_表面**temp_surf=SDL_Ex_ExtractFrames(_表面、框架宽度、框架高度、每行框架、每列框架、填充); int surface_count=每行帧数*每列帧数; 对于(int i=0;i,c++,iterator,containers,insert-iterator,C++,Iterator,Containers,Insert Iterator,,提到正在调用一个复制构造函数。在提供的示例中,容器似乎被定义为保存BlitSurface。类似于std::vector。这是我从以下几行中的猜测: for(int i=0; i<surface_count; ++i) { it->_surface = temp_surf[i]; ++it; } 我的理解是,所有std容器都会在插入时进行复制。从那时起,您可以通过引用使用容器中的对象。如果您不希望在BlitSurface上调用复制构造函数,那么我建议容器存储指向Bl
for(int i=0; i<surface_count; ++i)
{
it->_surface = temp_surf[i];
++it;
}
我的理解是,所有std容器都会在插入时进行复制。从那时起,您可以通过引用使用容器中的对象。如果您不希望在BlitSurface上调用复制构造函数,那么我建议容器存储指向BlitSurface的指针。这样,当容器在插入obje时进行复制时它实际上复制的ct是一个指针(不是指向的BlitSurface对象)
请记住,这种方法在堆上分配内存(即新的),因此以后必须显式删除内存,或者可以在容器中使用某种类型的智能指针来处理删除(std::vector
BlitSurface* bs = new BlitSurface;
bs->_surface = temp_surf[i];
*it = bs;
模板
结构移动特性{
typedef T must_copy_type;//在专门化中不存在
};
模板
结构移动\u如果可能\u分配器
:std::分配器{
类型定义移动特征;
//如果有专门化,SFINAE将选择此函数
void构造(typename traits::may_move_type*obj、T和value){
新建(obj)T();//默认构造
traits::move_obj(*obj,value);//自定义例程
}
//如果traits是基本模板,SFINAE将选择此函数
void构造(typename traits::must_copy_type*obj、T const和value){
新建(obj)T(值);//复制构造(回退情况)
}
//为读者定义重新绑定…练习;v)
};
模板
结构移动特征{
typedef T may_move_type;//表示存在专门化
静态无效移动对象(BlitSurface&out、BlitSurface&in){
//填写并清除
}
}
当然,如果某些对象实际上被复制到容器中,那么向BlitSurface添加状态以禁用通过
move\u obj
移动是完全可以的。定义了一个标准的insert\u迭代器
适配器来调用某个容器的insert
,该适配器反过来又被定义为使用复制构造函数--IOW,insert\u iterate或者
必须按照标准使用复制ctor。因此,您需要定义一个不同的适配器,以减少复制量(但是,如果您确实希望使用底层容器的插入
方法,您可能仍然需要复制至少一个新构建的默认项!)@Alex-我有个主意,但我不知道怎么做。我可以创建一个默认对象(_surface=NULL)。然后将其添加到容器中。在这种情况下,复制构造函数只需将_surface设置为NULL。然后,在事实发生后,我可以在容器中设置对象的成员。但是,同样,我无法将其用于插入迭代器。您知道如何做吗?@user,插入迭代器的标准实现adapter在operator=
中增加插入指针,因此,同样,您不能使用特定的适配器:您需要实现自己的专用迭代器适配器。您的代码对我来说是希腊语,但我理解您的解释。到目前为止,我一直避免使用分配器,我想是时候了解它们了。我现在无法有效地实现这一点,但你为我指明了正确的方向。谢谢。
BlitSurface bs;
bs._surface = temp_surf[i];
*it = bs;
BlitSurface* bs = new BlitSurface;
bs->_surface = temp_surf[i];
*it = bs;
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
}
}