【问题标题】:C++ array member without initialization没有初始化的 C++ 数组成员
【发布时间】:2014-11-10 12:30:35
【问题描述】:

我尝试编写一个“内联向量”类来方便地在堆栈上存储许多元素:

template<typename T, size_t size_ = 256>
struct InlineVector{
    T content[size_];
    size_t num;

    T() : num(0) {}

    ~T() { for(size_t s = 0; s < num; s++){ content[s]->~T(); } }

    template<typename _Up, typename... _Args>
    void emplace_back(_Args&&... __args) { new (&content[num++]) T(__args); }

    T& get(size_t i) { assert(i < num); return content[i]; }


}

出于效率原因,我希望content 不在X 的构造函数中初始化,即使T 只有一个非平凡的构造函数。如您所见,内容稍后会在实际插入时使用placement new 进行初始化。然而,C++ 似乎强制content 的所有元素必须在X 的初始化中进行初始化。例如,这不会编译:

struct Y{ Y(int){} }

X<Y> foo; // compile error, no constructor for Y is called in the construction of X

那么,即使数组元素类型需要构造函数,怎么可能有一个未初始化的数组成员呢?

【问题讨论】:

    标签: c++ arrays constructor


    【解决方案1】:

    通过使数组成为chars 的数组,然后将new-ing 放入其中。 char 是唯一允许您执行此操作的类型。

    当您使用它时,您不妨编写自己的 allocator(将数组作为其成员之一),并将其插入 std::vector 而不是重新发明了整个shebang。

    std::vector<int, YourAllocatorType<int, 256>> v;
    

    【讨论】:

    • 分配器的有趣想法。并感谢使用char 数组的实际答案,因为分配器会遇到与向量相同的问题。似乎没有办法绕过 char 数组,无论是编写分配器还是向量。
    • @gexicide: 是的,不是真的:)
    【解决方案2】:

    那么,即使数组元素类型需要构造函数,怎么可能有一个未初始化的数组成员呢?

    它不适用于T x[n]...但您可以将任何旧的T* 指向正确对齐的未初始化内存,然后管理您自己的临时构造和销毁。您还可以探索使用您的类型创建一个union 并说一个char,并拥有一个联合数组....

    【讨论】:

    • 我认为 union 不允许用于具有非平凡构造函数的成员。但这不是必需的; char 数组和强制转换很好,只要其中一种类型是 char,定义明确。
    • @JanHudec:类型有一些限制,但我相信对于 C++11 来说它们已经大大放宽了......当然要记住一些事情。现在没有时间自己去挖掘确切的细节......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2011-08-04
    • 2013-04-13
    • 2020-07-08
    相关资源
    最近更新 更多