一个具有unique_ptr字段但具有不同删除者的结构

时间:2013-04-28 19:52:19

标签: c++ visual-studio-2010 templates cuda unique-ptr

使用Visual Studio 2010,我有:

using namespace std;
struct C 
{
    unique_ptr<F1, default_delete<F1>> Field1;
    unique_ptr<F2, default_delete<F1>> Field2;
    unique_ptr<FN, default_delete<F1>> FieldN;
}

它将在两个上下文中使用,CPU和GPU,在结构和字段将具有default_dele的CPU上下文中,在GPU上下文中,使用CUDA,它们将具有自定义删除器它使用cudaFree函数删除。

可能使用的自定义删除器看起来像这样

struct DevDeleter
{
    void operator()(void* d_ptr)
    {
        cudaError_t error = cudaFree(d_ptr);
        if (error != cudaSuccess)
        {
            throw;
        }
    }
}

所以,我的第一个预感是看模板,我的结构变成了:

template<typename Deleter> 
struct C 
{
    unique_ptr<F1, Deleter> Field1;
    unique_ptr<F2, Deleter> Field2;
    unique_ptr<FN, Deleter> FieldN;
}

我有一个结构框架(超过30个)需要在2个删除上下文中工作。如果我想在某个函数中声明struct C,那么这将有一个递归声明,无法写入:

unique_ptr<C<default_delete<C<default_delete<C<(recursive)>>>>, default_delete<C(recursive)>> c(new C<...>());

您是否有改进或干净的解决方案以允许结构为其成员提供自定义unique_ptr删除器?

N.B。我知道我可以进行模板特化,但这实际上是复制了结构。

3 个答案:

答案 0 :(得分:2)

我认为这就是你想要的:

template <typename T>
struct DevDeleter
{
    void operator()(T* d_ptr)
    {
        cudaError_t error = cudaFree(d_ptr);
        if (error != cudaSuccess)
        {
            throw;
        }
    }
}

然后你可以有这样的模板:

template<template <typename> class Deleter>
struct C 
{
    unique_ptr<F1, Deleter<F1>> Field1;
    unique_ptr<F2, Deleter<F2>> Field2;
    unique_ptr<FN, Deleter<FN>> FieldN;
}

并将其称为:

C c_default<default_delete>;

或者

C c_dev<DevDeleter>;

答案 1 :(得分:0)

这样做:

template <typename T, typename D = std::default_deleter<T>> struct Foo
{
    std::unique_ptr<T, D> up;

    Foo(D const & d = D()) : up(nullptr, d) { }
};

示例:

// contains std::unique_ptr<int, std::default_deleter<int>>
Foo<int> x;

// contains std::unique_ptr<Bar, BarDeleter>
Foo<Bar, BarDeleter> y(BarDeleter(1, true, Blue));

答案 2 :(得分:0)

作为@ VaughCato答案的延伸,请考虑制作:

template<template <typename> class Deleter = std::default_delete>
struct C 
{
    template <typename T> using unique_ptr = unique_ptr<T, Deleter<T>>;
    unique_ptr<F1> Field1;
    unique_ptr<F2> Field2;
    unique_ptr<FN> FieldN;
}

电话会是这样的:

C<> c1;               // defaults to default_delete ...
C<default_delete> c2; // same thing but explicit
C<DevDeleter> c3;     // on device

H-o-w-e-v-e-r通过结构C“附加”删除逻辑而不是在创建这些唯一指针的位置,似乎有点可疑。它可能是合法的,但我会调查它。