C ++编译类型资源所有者断言

时间:2014-06-20 11:51:49

标签: c++ resources compile-time ownership

class Resource;

class Device
{
    ...
public:
    Resource createResource();

    bindResource(const Resource&);
};

int main()
{
    Device dev;
    Device oops;

    auto res = dev.createResource();

    dev.bindResource(res); // Okay; dev created this resource

    oops.bindResource(res); // Error: oops did not create this resource
}

Program does not compile

这可以在编译时完全完成,没有运行时开销和类似的语法吗? 例如,device是Direct3D渲染器的抽象;我们不能共享一些资源,如果我们尝试,应该是编译时错误。

1 个答案:

答案 0 :(得分:0)

有一种解决方法,它使用__COUNTER__宏。虽然标准没有提供,但MSVC和GCC支持它。此宏涉及一个整数值,每次在转换单元中使用此宏时,该值都会递增。因此,实现如下:

// Device.h
#define DEVICE Device<__COUNTER__>

template<int N>
class Device
{
public:
    class Resource{};
    Resource createResource() { return Resource(); }
    void bindResource(const Resource&) {}
};

如您所见,Resource类现在在Device类中声明。应使用Device宏声明DEVICE类的所有实例。现在,devoops实例被实例化为不同类型的对象。 devDevice<0>oopsDevice<1>。并且,res现在分别为Device<0>::Resource,而oops无法绑定它。

然而,这种方法具有以下缺点(至少):
1)将设备作为函数参数传递是一个问题。为了保证编译时检查,处理设备的所有功能也应该是模板。这可能会导致严重的代码膨胀 2)如果声明DEVICE类型的数组(例如,DEVICE devices [10]),则所有设备将是相同的类型,因此,将能够绑定彼此的资源。
3) __ COUNTER __ 宏仅通过单个翻译单元提供唯一值。如果您在一个翻译单元的开头声明dev而在第二个翻译单元的开头声明oops,则其类型将相同,oops将能够绑定{{ 1}}的资源 4)标准不提供 __ COUNTER __

毕竟,我不建议您使用此解决方法,它可能仅用于教育目的:)