我想自定义std::vector
行为以不默认构造元素类型(例如int
),因为对于大向量来说这样做很昂贵。
对此,我看到的唯一方法是专门研究std::allocator_traits<MyAllocator>::construct
。但是,这似乎是不可能的,因为专门化必须与原始声明位于相同的名称空间中。
在namespace std
中放入专业名称似乎并不正确。而且实际上比这更糟,因为我正在使用的STL实现实际上将std::allocator_traits
放在namespace std::__u
中(并且肯定会在STL实现中有所不同),所以这样做似乎是非常错误的。
这令人困惑,因为它看起来像std :: allocator_traits旨在允许专门化,但我不知道如何实际进行。这仅仅是个坏主意吗?如果是这样,还有其他解决方法(避免在STL容器中默认构造元素)吗?
不仅允许对标准库特征类进行专业化,而且是提供此类功能的主要方法。但是,在这种特定情况下,这是不必要的。
默认的std::allocator_traits<T>::construct
实现(其中T
是您的分配器类型,而不是与其使用的容器的值类型)将调用construct
的T
成员函数,如果T
具有函数,如果new
没有合适的成员,它将调用Placement- T
。因此,只需为您的分配器分配一个construct
成员,就可以了。
您应该呼叫reserve
,而不是resize
。仅当值已知时才添加元素。没有必要创建充满垃圾的vector
。
std::vector<int> v;
r.reserve(500);
v.push_back(3); // Only 1 constructor is called
如果您真的不想初始化数据但仍然要填充它,那么可以使用带有未初始化其成员的构造函数的struct
;
struct unintialized_int
{
unintialized_int() { /* no initialization */ }
int uninitialized;
};
std::vector<unintialized_int> v;
v.resize(500);
v[22].uninitialized = 33;
但是,我不建议这样做,因为它可能导致难以发现错误!最好按预期使用矢量。
通过诸如int
之类的琐碎类型影响性能的方法,您必须具有数千个项目或创建数千个向量。
一些要问自己的问题:
int
这样的琐碎类型,编译器可能能够将初始化优化为memset
。