如何为std :: unique_ptr创建有效的C ++别名模板

多米尼克·多斯·桑托斯

我想为此std::unique_ptr提供自己的删除器功能的别名模板

unique_ptr 具有标量和数组实现,它们的定义如下:

template <class T, class D = default_delete<T>>
class unique_ptr // scalar

template <class T, class D>
class unique_ptr<T[], D> // array

我在尝试覆盖的标量和数组版本时遇到麻烦unique_ptr为一个版本创建别名很容易,如下所示:

template<class T>
struct Deleter {
    void operator()(T* ptr) { delete ptr; }
};

template<class T>
using my_unique_ptr = std::unique_ptr<T Deleter<T>>;

但是,当我尝试添加第二个别名时,如下所示:

template<class T>
struct ArrayDeleter {
    void operator()(T* ptr) { delete [] ptr; }
};
template<class T>
using my_unique_ptr = std::unique_ptr<T[], ArrayDeleter<T>>;

...由于“ my_unique_ptr”含糊不清,最终导致编译器错误

我的问题是:如何创建一个既适用于数组又适用于标量版本的别名unique_ptr

Yakk-亚当·内夫罗蒙特

您似乎正在尝试专门处理using声明。你不可以。

template<class T>
struct my_unique_ptr_helper {
  using type = std::unique_ptr<T, Deleter<T>>;
};
template<class T>
struct my_unique_ptr_helper<T[]> {
  using type = std::unique_ptr<T[], ArrayDeleter<T>>;
};

template<class T>
using my_unique_ptr = typename my_unique_ptr_helper<T>::type;

现在,这样做的缺点在于,它相当完全地阻止了演绎。

我们可以通过将专业化转移到其他地方来解决此问题。

template<class T>
struct Deleter {
  void operator()(T* ptr) const {
    delete ptr;
  }
};
template<class T>
struct ArrayDeleter {
  void operator()(T* ptr) const {
    delete[] ptr;
  }
};
template<class T>
struct Deleter<T[]>:ArrayDeleter<T> {}; // inheritance

现在:

template<class T>
using my_unique_ptr = std::unique_ptr<T, Deleter<T>>;

更简单,并且可以允许更多的推导T

当然,这一切Deleter都没有意义,但我想您的真实情况与并不相同std::default_delete

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章