在NVidia 的 TensorRT 庫提供的 C 示例中,有一個名為的檔案common.h,其中包含整個示例中使用的結構的定義。
除其他外,該檔案包含以下定義:
struct InferDeleter
{
template <typename T>
void operator()(T* obj) const
{
delete obj;
}
};
template <typename T>
using SampleUniquePtr = std::unique_ptr<T, InferDeleter>;
在SampleUniquePtr整個代碼示例中使用別名來包裝指向某些函式回傳的介面類的各種指標,例如SampleUniquePtr<INetworkDefinition>(builder->createNetworkV2(0));
我的問題是,在哪些實際方面是不同std::unique_ptr的SampleUniquePtr?的行為SampleUniquePtr幾乎是我所期望的std::unique_ptr,至少現在是這樣。可能是為了與舊版本的 C 兼容?
uj5u.com熱心網友回復:
從歷史上我看到它有一段時間了
template <typename T>
void InferDeleter::operator()(T* obj) const
{
if (obj)
{
obj->destroy();
}
}
然后他們宣布destroy()不推薦使用的方法:
- 具有方法的類的解構式
destroy()以前受到保護。它們現在是公開的,可以為這些類使用智能指標。這些destroy()方法已棄用。
雖然它已被棄用,但它仍然沒有被洗掉,并且InferDeleter應該保留舊的 ABI,以便與舊的 TensorRT 鏈接的應用程式向后兼容。因此他們從最近開始使用
template <typename T>
void InferDeleter::operator()(T* obj) const
{
delete obj;
}
不洗掉struct InferDeleterand using SampleUniquePtr = std::unique_ptr<T, InferDeleter>。但將來可能會被洗掉。當他們洗掉struct InferDeleter和更改using SampleUniquePtr = std::unique_ptr<T>時,它會使 TensorRT 庫與舊軟體不兼容。
uj5u.com熱心網友回復:
我沒有時間掃描整個鏈接庫,所以我有可能在這個計數上錯了。
但是,您看到的可能是一個默認實作,它用作任何不需要特殊處理的型別的后備。
庫實作者總是可以選擇在他們正在處理實際上確實需要特殊處理的型別的情況下專門化此函式,這對于 Nvidia 制作的庫可能很常見(因此可能意味著與 GPU 互動)。
class GPUResource {
//...
~GPUResource() noexcept {} //Does NOT perform the special handling, for whatever library-specific reason
};
template<>
void InferDeleter::operator()<GPUResource>(GPUResource * obj) {
performSpecialCleanupOnGPUResource(obj->handle);
delete obj;
}
在實踐中,這種東西總是聞起來像一種反模式(你確定,庫實作者,你不能在這個物件的解構式中進行清理嗎??)但如果他們有充分的理由分離邏輯像這樣,他們定義的方式InferDeleter允許他們這種靈活性。
uj5u.com熱心網友回復:
該示例看起來毫無意義,因為這正是我期望默認洗掉器執行的操作。
但也許這更好(未經測驗):
#include <vector>
struct VectorDeleter
{
template <typename T>
void operator()(std::vector<T*> *v) const
{
for(auto p : *v) delete p;
delete v;
}
};
template <typename V>
using UniquePtrVector = std::unique_ptr<V, VectorDeleter>;
當您有一個指標向量(例如多型類)時,您必須在洗掉該向量時洗掉該向量指向的物件。VectorDeleter 在向量本身被洗掉之前執行此操作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/477232.html
