编译时间方法以确定对象是否具有自动存储持续时间

时间:2013-10-08 11:56:35

标签: c++ memory-management stack metaprogramming

我希望能够在编译时强制执行特定类型只能用于创建自动存储持续时间的对象。

template<typename T, typename Alloc>
struct Array
{
    T* data; // owned resource
    Array(std::size_t size); // allocates via Alloc
    ~Array(); // deallocates via Alloc
};

typedef Array<int, AutoAllocator<int>> AutoArray;

void foo(AutoArray a) // ok
{
    AutoArray l = AutoArray(); // ok
    static AutoArray s; // error
    new AutoArray(); // error
    std::vector<AutoArray> v(1); // error
}

此应用程序的目的是为AutoArray实例所拥有的资源选择最佳分配策略。这个想法是具有自动存储持续时间的对象所需的资源分配模式与LIFO资源分配器兼容。

我可以用什么方法在C ++中实现这个目标?

编辑:次要目标是通过放入Array或默认AutoAllocator来允许std::allocator的分配策略透明切换。< / p>

typedef Array<int, std::allocator<int>> DynamicArray;

假设有大量代码已经使用DynamicArray

1 个答案:

答案 0 :(得分:2)

这不可能。考虑您创建了一个将其作为成员保存的类型。当编译器为该类型的构造函数生成代码时,它不知道对象的创建位置,堆栈中的完整对象是否在堆中?

您需要使用不同的思维模式解决您的问题,例如,您可以将分配器传递给对象的构造函数(BSL的方式)并且可能默认为安全分配器(基于new -delete),然后对于那些用户可以明确请求它的更好选项的用例。

这与编译器错误不同,但在代码审查中检测它会很明显。

如果您真的对分配器的有趣用途感兴趣,您可能需要查看标准库的BSL替换,因为它允许传播到容器成员的多态分配器。在BSL世界中,您的示例将成为:

// Assume a blsma::Allocator implementing LIFO, Type uses that protocol
LifoAllocator alloc;       // implements the bslma::Allocator protocol
Type l(&alloc);            // by convention bslma::Allocator by pointer
static Type s;             // defaults to new-delete if not passed
new (&alloc) Type(&alloc); // both 'Type' and it's contents share the allocator
                           // if the lifetime makes sense, if not:
new Type;                  // not all objects need to use the same allocator
bsl::vector<Type> v(&alloc);
v.resize(1);               // nested object uses the allocator in the container

通常使用分配器并不简单,您必须注意对象相对于彼此和分配器的相对生命周期。