1

使用 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,在 CPU 上下文中,结构和字段将具有 default_delete 和在 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;
}

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

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

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

注意我知道我可以进行模板专业化,但这实际上是在复制结构。

4

3 回答 3

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>;
于 2013-04-28T21:02:44.913 回答
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));
于 2013-04-28T20:09:04.547 回答
0

作为@VaughCato's answer的扩展,请考虑使其:

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

但是,您通过 struct C 而不是在创建这些唯一指针的位置“附加”了删除逻辑,这似乎有点可疑。这可能是合法的,但我会调查一下。

于 2016-02-23T18:50:06.797 回答