使用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。我知道我可以进行模板特化,但这实际上是复制了结构。
答案 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“附加”删除逻辑而不是在创建这些唯一指针的位置,似乎有点可疑。它可能是合法的,但我会调查它。