我在实现如下构造时遇到了问题。我的想法是我在一些头文件中定义了一个实用程序函数,它分配了某种资源。为了减轻客户自己释放它的必要性,我想把它包装成一个智能指针。 不幸的是,我不得不将删除器类型提供给客户端,并且无法正确地向前声明它。我当前的解决方案看起来像这样,导致多个定义错误,因为删除器是使用utilities.h的每个附加包含重新定义的。
这是我正在寻找的优雅解决方案?
// utilities.h
namespace foo
{
auto del = []( MyResource* res) { Deallocate( res ); };
std::unique_ptr<MyResource, decltype(del)> getResource( );
}
// utilities.cpp
namespace foo
{
std::unique_ptr<MyResource, decltype(foo::del)> getResource( )
{
return std::unique_ptr<MyResource, decltype(foo::del)>( Allocate( ), del );
}
}
答案 0 :(得分:5)
使用普通类而不是lambda:
部首:
namespace foo {
struct Deleter {
void operator() (MyResource *res) const { Deallocate(res); }
};
std::unique_ptr<MyResource, Deleter> getResource();
}
来源:
namespace foo
{
std::unique_ptr<MyResource, decltype(foo::del)> getResource( )
{
return std::unique_ptr<MyResource, Deleter>( Allocate( ) );
}
}
这还有一个额外的好处,就是在创建指针时不必指定删除器 - 默认构造的Deleter
就可以了。
答案 1 :(得分:0)
我建议Angew's answer超过这个主要是因为std::function
中类型擦除的额外开销。很高兴知道这种方式也是可行的。
修复很简单:在头文件中有声明,源代码中有定义:
// utilities.h
namespace foo {
using del_t = std::function<void(MyResource *)>;
extern del_t del;
std::unique_ptr<MyResource, del_t> getResource();
}
// utilities.cpp
namespace foo {
del = [](MyResource* res) {
Deallocate(res);
};
std::unique_ptr<MyResource, del_t> getResource() {
return std::unique_ptr<MyResource, del_t>(Allocate(), del);
}
}