添加在aaronman的帖子之上。尽管您不能单独使用模板类,但使用一些帮助程序(包括宏)是可能的:
template <typename T>
T deduce(void(*)(T*));
#define CALLFN(f) callfn<decltype(deduce(f)), f>
使用示例:
CALLFN(call) fun; // instead of 'callfn<call> fun;' as asked
但是,从 OP 的评论来看,这只是一个问题的一部分,没有这一部分的解决方案似乎更简单。
如果我理解正确,您想使用自定义函数删除器(类型)std::unique_ptr
为某种类型创建一个,但您不希望在. 例如,考虑:T
f
void (*)(T*)
std::unique_ptr
class MObj { /* ... */ };
void mfree(MObj*) { /* ... */ }
正如在 OP 的评论中所说,我们通常有
std::unique_ptr<MObj, void(*)(MObj*)> p1(nullptr, mfree);
assert(sizeof(p1) == sizeof(MObj*) * 2);
但使用callfn
我们可以节省空间:
std::unique_ptr<MObj, callfn<MObj, mfree>> p2;
assert(sizeof(p2) == sizeof(MObj*));
我相信上述解决方案的唯一烦恼是需要输入callfn
两次MObj
。那么,这个呢:
template <typename T, void (*f)(T*)>
using light_unique_ptr = std::unique_ptr<T, callfn<T, f>>;
light_unique_ptr<MObj, mfree> p3; // 1
assert(sizeof(p3) == sizeof(MObj*));
我也明白(也许我错了)意图是更短的东西,比如
lighter_unique_ptr<mfree> p4; // 2
assert(sizeof(p4) == sizeof(MObj*));
并让编译器从mfree
. 正如我所指出的,这可以通过宏来完成,但我认为这不是一件好事,原因有两个:
mfree
如果我们对(比如void mfree(MObj*)
和)有不同的重载,它就不起作用void mfree(Foo*)
。
- 用户通常希望
std::unique_ptr
在其实例化中看到指向的 a 类型,并(最终)看到它的删除器。上面的第 1 行确实显示了类型 ( MObj
),但第 2 行没有。看不到类型可能会让某些人感到困惑。
我同意上面的第二点是有争议的(类似于我应该使用汽车的辩论)。