【问题标题】:Possibility to construct std::tuple's elements later with an allocator?以后可以用分配器构造 std::tuple 的元素吗?
【发布时间】:2013-12-23 22:40:09
【问题描述】:

据我了解,将 C++ 的分配器用于我自己的容器的一个原因是我可以将分配和构造分开。

现在,我想知道这是否可以通过以下方式对 std::tuples 进行:每次构造 std::tuple 时,都会保留空间,但还没有构造对象。相反,我可以使用分配器来在我想要的时候构造第 i 个参数。

伪代码:

struct my_struct {
    const bool b; // note that we can use const
    my_struct(int x) : b(x==42) {}
};

int main()
{
    std::tuple<int, my_struct> t;
    // the tuple knows an allocator named my_allocator here
    // this allocator will force the stack to reserve space for t,
    // but the contained objects are not constructed yet.

    my_allocator.construct(std::get<0>(t), 42);
    // this line just constructed the first object, which was an int
    my_allocator.construct(std::get<1>(t), std::get<0>(t));
    // this line just constructed the 2nd object
    // (with help of the 1st one

    return 0;
}

一个可能的问题是分配器通常绑定到一个类型,所以我需要每个类型一个分配器。另一个问题是 std::tuple 的内存是否必须在堆上分配,或者堆栈是否可以工作。两者都适合我。

不过,有可能吗?或者如果没有,这可以通过我自己编写的分配器来完成吗?

【问题讨论】:

  • 试试std::get_temporary_buffer 以及未初始化的存储算法。
  • 这里有一些 proof of concept code 演示了我如何做到这一点,但我完全不知道这是否是有效的 C++。
  • @KerrekSB:使用对象或对此类对象的引用/指针调用的任何标准库函数的前提是该对象存在(除非另有明确说明)。显然,在未初始化的内存中没有对象。
  • @DietmarKühl:我希望有某种“&amp;* 不计算操作数”的魔法......我也在考虑成员指针,但不知道如何获得其中之一对于元组(在这种情况下,“基指针”可能是正确的)。
  • @KerrekSB 不确定,也许这就是我想要的。 new 代码行是什么意思?对应this doc的哪个版本?我猜是第 3 版?

标签: c++ c++11 allocator stdtuple


【解决方案1】:

分配器不会帮助您初始化对象:分配器的作用是提供原始,即未初始化的内存。分配器可以与 std::tuple&lt;...&gt; 一起使用,以自定义分配方式,例如分配 std::stringstd::vector&lt;...&gt; 的内存。

如果您想延迟对象的构建,您需要使用类似“可选”对象之类的东西,它会用标志指示它尚未构建。相应类的实现策略将是一个合适的union 的包装器。

【讨论】:

  • 谢谢,但能否请您详细说明一下?它与联合(或者可能是变体)有什么关系?请注意,我不想只初始化元组的一个元素,但可能是多个,并且它们应该同时存在。
  • 另外,对于原始内存参数:如果您可以在堆上分配std::tuple 的空间,对您有帮助吗?
  • @Johannes: union 是将尚未构建的对象可移植地嵌入到另一个对象中的唯一方法(例如,相同大小的数组可能无法工作,因为初始化问题)。如果多个元素放在一起,您可能希望将它们放入嵌套的 std::tuple&lt;...&gt; 中(并且可能使用认为它们不嵌套的自定义 get&lt;...&gt;() 函数)。
  • @Johannes:死对象就是死对象。没有在哪里构造对象无关紧要:在构造之前,您不能[可移植地]使用它。
  • @Johannes:有一个example at Wikipedia 使用unions 在一个位置构造不同的对象,但是应该直截了当地使用可选构造的对象来做同样的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多