自定义std :: allocator_traits :: construct

问题描述 投票:0回答:2

我想自定义std::vector行为以不默认构造元素类型(例如int),因为对于大向量来说这样做很昂贵。

对此,我看到的唯一方法是专门研究std::allocator_traits<MyAllocator>::construct。但是,这似乎是不可能的,因为专门化必须与原始声明位于相同的名称空间中。

namespace std中放入专业名称似乎并不正确。而且实际上比这更糟,因为我正在使用的STL实现实际上将std::allocator_traits放在namespace std::__u中(并且肯定会在STL实现中有所不同),所以这样做似乎是非常错误的。

这令人困惑,因为它看起来像std :: allocator_traits旨在允许专门化,但我不知道如何实际进行。这仅仅是个坏主意吗?如果是这样,还有其他解决方法(避免在STL容器中默认构造元素)吗?

c++ stl allocator
2个回答
1
投票

不仅允许对标准库特征类进行专业化,而且是提供此类功能的主要方法。但是,在这种特定情况下,这是不必要的。

默认的std::allocator_traits<T>::construct实现(其中T是您的分配器类型,而不是与其使用的容器的值类型)将调用constructT成员函数,如果T具有函数,如果new没有合适的成员,它将调用Placement- T。因此,只需为您的分配器分配一个construct成员,就可以了。


-1
投票

您应该呼叫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
  • 您确定初始化对性能有可衡量的影响吗?
© www.soinside.com 2019 - 2024. All rights reserved.