我最近遇到了一个旧的C函数,它返回了一个指向静态数组的指针。我围绕该函数编写了一个包装器,并返回了一个std::unique_ptr
,该使用no-delete来强调返回的指针类型 - 向用户发出"不要删除我"警告。下面是一个示例代码
extern "C" int *f(int i);
struct noop
{
template <typename T>
void operator() (T t) const noexcept
{
}
};
class MyClass
{
public:
std::unique_ptr<int, noop> F(int value) const
{
return std::unique_ptr<int, noop>(f(value));
}
};
有没有一种更干净的方法来做到这一点,而无需定义无删除结构?
[..] 一个旧的 C 函数,返回指向静态数组的指针。我写了 该函数的包装器并返回
std::unique_ptr
不要。返回std::unique_ptr
对呼叫者说:
- 你拥有这段记忆,清理自己
- 您拥有此内存,没有其他人会干涉(线程安全(
- 你拥有这段记忆。因此,每次调用时都会得到一个新对象(包装函数(。
对于指向静态数组的指针,这些都不是真的!
坚持使用原始指针或使用一些包装类来允许类似引用的访问。 例如,std::reference_wrapper
复制时还提供原始指针等语义。
C++编码指南建议使用别名或"虚拟"包装器来指示所有权或非空性:
- I.12:将不得为 null 的指针声明为 not_null
- I.11:切勿通过原始指针 (T*( 或引用 (T&( 转让所有权
对于它们的实现,请查看:
https://github.com/Microsoft/GSL/blob/master/include/gsl/pointers
您将看到owner<>
和non_null<>
的示例。
你可以类似的定义。显然,不得删除非拥有指针;如果您只是想要提醒,那么
template <class T, class = std::enable_if_t<std::is_pointer<T>::value>>
using non_owner = T;
如果您想强制执行,请从链接中复制并调整代码以进行non_null<>
。