【发布时间】:2021-05-02 11:01:02
【问题描述】:
nvinfer1::IRuntime 和nvinfer1::ICudaEngine 等NVIDIA TensorRT 对象不能直接存储在std::unique_ptr<> 中。相反,他们有一个必须调用的destroy() 方法。
因此,要使其工作,您必须使用这样的删除器:
#include <NvInfer.h>
#include <cuda.h>
template<typename T>
struct NVIDIADestroyer
{
void operator()(T * t)
{
t->destroy();
}
};
template<typename T>
using NVIDIAUniquePtr = std::unique_ptr<T, NVIDIADestroyer<T>>;
然后你使用NVIDIAUniquePtr<T>,而不是std::unique_ptr<T>。
到目前为止,这工作正常。然后我在清理代码时尝试做的是用 lambda 替换删除器,这样我就可以跳过定义 NVIDIADestroyer 结构。但我无法弄清楚如何做到这一点。我的想法是这样的:
template<typename T>
using NVIDIAUniquePtr = std::unique_ptr<T, [](T * t)
{
t->destroy();
}>;
但这会导致以下错误消息:
TRT.hpp:52:45: error: lambda-expression in template-argument
using NVIDIAUniquePtr = std::unique_ptr<T, [](T * t)
^
TRT.hpp:55:2: error: template argument 2 is invalid
}>;
^
有没有办法让它工作?
【问题讨论】:
-
这是由this question 回答的,虽然它不是重复的(我确定有一个,只是现在找不到)。
-
为什么你认为 lambda 方法会更好?自定义删除器在一个地方解决了问题,您完成了,使用 lambda 的版本每次创建
std::unique_ptr时都必须处理自定义删除器。 -
在 C++20 中你可以拥有
template <typename T> using NVIDIADestroyer = decltype([](T* t){ t->destroy(); }); -
C++ 一直在为此使用自定义类型。 (以前有比较器)在 C++20 之前,您可以使用函数指针作为类型,并在指针中传递对象(除了 unique_ptr 不允许,仅用于比较器对象)但使用类型使优化器更容易内联代码。在 C++20 中,lambda 只是用于定义结构的语法糖。 tl;dr:您已经拥有的代码是惯用的 C++
-
@MichaëlRoy 不必要的开销。
标签: c++ lambda c++17 unique-ptr tensorrt