C++模版是怎么一回事

     学习C++一直对这块不是很了解,今天有时间搞搞,模版的概念是在C++ 语言的高版本才引进的, 模版是参数化的类型,在有模版之前 C++ 语言的程序员热衷于设计类属一类 ,其目标是为了实现程序代码的可重用性,通过属性编程,使得同一结构 的不同实例公用同样的代码,这样的类属性数据结构包括:桟 队列,数组 矩阵 链表,二叉树 算列表 图,可以节省代码和易于维护

  函数模板说明
函数模板定义的一般格式为:
template < <模板参数表> > < 函数定义 >;
其中:
template:关键字。指明为函数模板或类模板。
模板参数表:用尖括号括起来,一个或多个模板参数,用“,”分开。
模板参数:其格式为class<类名>,其中的类名是一个标识符,该类名对应
的实参类型可以是系统预定义类型如int、char 等,也可以是用户自定义类型。
函数定义:与一般函数定义一样:
<返回类型><函数名>(<参数表>){<函数体>};
应注意的是,在模板参数表中的类型参数应出现在上述的“<返回类型>”
或“<参数表>”或“<函数体>”之中(否则将没有可变性,只能定义出一个具
体的函数)。



利用类模板(带类型参数或普通参数的类),一次就可定义出具有共性(除
类型参数或普通参数外,其余全相同)的一组类。即是说,与使用函数模板的
优越性相似,通过使用类模板,可使得所定义类中的某些数据成员、某些成员
函数的参数、某些成员函数的返回值都可以是任意类型的(包括系统预定义类
型以及用户自定义类型)。也可以这样说,通过类模板可将程序所处理对象(数
据)的类型参数化,从而使得同一段程序可用于处理多种不同类型的对象(数
据),提高了程序的抽象层次与可重用性





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的TensorRT C++部署模板,你可以根据自己的需求进行修改: ```c++ #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <ctime> #include "NvInfer.h" #include "NvOnnxParser.h" #include "NvUffParser.h" #include "NvInferPlugin.h" #include "NvUtils.h" using namespace nvinfer1; using namespace nvonnxparser; using namespace nvuffparser; using namespace plugin; // 定义输入和输出张量大小 const int BATCH_SIZE = 1; const int INPUT_CHANNEL = 3; const int INPUT_HEIGHT = 224; const int INPUT_WIDTH = 224; const int OUTPUT_SIZE = 1000; // 定义TensorRT日志回调函数 void logCallback(const char* msg, const char* /*file*/, int /*line*/) { std::cout << "[TensorRT] " << msg << std::endl; } int main(int argc, char** argv) { // 创建Logger对象 Logger logger; logger.log(ILogger::Severity::kINFO, "TensorRT version: " + std::to_string(getInferLibVersion())); // 创建Builder对象 IBuilder* builder = createInferBuilder(logger); if (!builder) { std::cerr << "Failed to create builder." << std::endl; return -1; } // 创建NetworkDefinition对象 INetworkDefinition* network = builder->createNetwork(); if (!network) { std::cerr << "Failed to create network." << std::endl; return -1; } // 创建ONNX解析器对象 IParser* parser = createParser(*network, logger); if (!parser) { std::cerr << "Failed to create parser." << std::endl; return -1; } // 从ONNX模型文件中解析网络结构 std::string onnxModelFile = "model.onnx"; parser->parseFromFile(onnxModelFile.c_str(), static_cast<int>(ILogger::Severity::kWARNING)); if (parser->getNbErrors() > 0) { std::cerr << "Failed to parse ONNX model." << std::endl; return -1; } // 构建推理引擎 builder->setMaxBatchSize(BATCH_SIZE); builder->setMaxWorkspaceSize(1 << 30); builder->setFp16Mode(true); builder->setInt8Mode(false); ICudaEngine* engine = builder->buildCudaEngine(*network); if (!engine) { std::cerr << "Failed to build engine." << std::endl; return -1; } // 创建ExecutionContex对象 IExecutionContext* context = engine->createExecutionContext(); if (!context) { std::cerr << "Failed to create execution context." << std::endl; return -1; } // 分配输入和输出内存 std::vector<float> inputData(BATCH_SIZE * INPUT_CHANNEL * INPUT_HEIGHT * INPUT_WIDTH); std::vector<float> outputData(BATCH_SIZE * OUTPUT_SIZE); // 生成随机数据作为输入 srand(time(nullptr)); for (size_t i = 0; i < inputData.size(); i++) { inputData[i] = static_cast<float>(rand()) / RAND_MAX; } // 将输入数据传输到显存中 void* inputDevice = nullptr; cudaMalloc(&inputDevice, inputData.size() * sizeof(float)); cudaMemcpy(inputDevice, inputData.data(), inputData.size() * sizeof(float), cudaMemcpyHostToDevice); // 分配GPU内存作为输出 void* outputDevice = nullptr; cudaMalloc(&outputDevice, outputData.size() * sizeof(float)); // 创建CUDA流 cudaStream_t stream = nullptr; cudaStreamCreate(&stream); // 执行推理 std::vector<void*> bindings(2); bindings[0] = inputDevice; bindings[1] = outputDevice; context->enqueueV2(bindings.data(), stream, nullptr); cudaStreamSynchronize(stream); // 将输出数据从显存中传输回CPU内存 cudaMemcpy(outputData.data(), outputDevice, outputData.size() * sizeof(float), cudaMemcpyDeviceToHost); // 打印输出结果 for (size_t i = 0; i < outputData.size(); i++) { std::cout << outputData[i] << " "; } std::cout << std::endl; // 释放资源 cudaStreamDestroy(stream); cudaFree(inputDevice); cudaFree(outputDevice); context->destroy(); engine->destroy(); network->destroy(); parser->destroy(); builder->destroy(); return 0; } ``` 在这个模板中,我们首先创建了一个Logger对象用于记录TensorRT的日志信息,然后创建了一个Builder对象用于构建推理引擎,接着创建了一个NetworkDefinition对象用于描述网络结构,然后创建了一个ONNX解析器对象用于从ONNX模型文件中解析网络结构,接着使用Builder对象构建推理引擎,创建ExecutionContex对象用于推理,分配输入和输出内存并生成随机数据作为输入,将输入数据传输到显存中,然后执行推理,将输出数据从显存中传输回CPU内存,并打印输出结果。最后释放资源。 需要注意的是,在实际应用中,你需要根据自己的模型及数据进行修改。同时,这里使用了FP16精度模式和CUDA流进行加速,如果你的GPU不支持FP16精度模式,可以将其设置为false。如果你不需要使用CUDA流,可以直接传入nullptr。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值