我想为此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
?
您似乎正在尝试专门处理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] 删除。
我来说两句