如何转发声明自定义unique_ptr

How to forward declare custom unique_ptr

本文关键字:自定义 unique ptr 声明 何转发 转发      更新时间:2023-10-16

我在实现如下结构时遇到问题。这个想法是,我在一些头文件中定义了一个实用程序函数,用于分配某种资源。为了减轻客户自己释放它的必要性,我想把它包装成一个智能指针。不幸的是,我不得不以某种方式将deleter类型发送到客户端,并且在正确地向前声明它时遇到了问题。我目前的解决方案是这样的,导致了多个定义错误,因为删除程序是用每个附加的实用程序重新定义的。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 );
  }
}

使用普通类而不是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( ) );
  }
}

这还有一个额外的优点,即在创建指针时不必指定删除程序—默认构造的CCD_ 1将做得很好。

我推荐Angew的答案,主要是因为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);
  }
}