C function pointer

function pointer

以下是宣告function pointer的方式:

/*
int square(int x){
    return x * x;
}
*/

int (*fnc_ptr)(int) = □

function pointer是一種指向一段可執行代碼起始位置的指標。在上例中,fnc_ptr指向的是square這個函數。我們可以使用如下方式來調用它:

std::cout << (*fnc_ptr)(10) << std::endl;

注意到我們使用&來獲取square函數的位置,並使用*來從function pointer中獲取函數本身。但其實我們也可以用函數名本身獲取其地址,如下例:

int (*fnc_ptr2)(int) = square;
std::cout << fnc_ptr2(10) << std::endl;

可以看到,省略square前的&fnc_ptr2*後,代碼仍可運行。

typedef function pointer

在上例中,如果我們想定義一個指向"接受一個int參數,回傳int"的函數指標,就得使用:

int (*fnc_ptr)(int);

事實上我們可以運用typedef,這樣就使用較簡單的語法來達到相同的目的:

typedef int(*MyFnc)(int);
MyFnc f = square;
std::cout << f(10) << std::endl;

以上寫法看著不太自然,但如果我們把MyFnc用它的定義int(*MyFnc)(int)來做替換,就會變成:

int(*f)(int) = square;

即,使用typedef前的寫法,完整代碼詳見cpp-code-snippets/function_pointer.cpp

TensorRT/parsers/caffe/caffeParser/opParsers/opParsers.h中也使用了typedef來定義一個function pointer型別:

typedef nvinfer1::ILayer* (*LayerParseFn)(nvinfer1::INetworkDefinition&, const trtcaffe::LayerParameter&, CaffeWeightFactory&, BlobNameToTensor&);

這裡定義:接受 nvinfer1::INetworkDefinition&, const trtcaffe::LayerParameter&, CaffeWeightFactory&, BlobNameToTensor& 為參數,回傳 nvinfer1::ILayer* 的函數指標名為LayerParseFn

function pointer as template argument

既然functoin pointer是一種型別,那麼我們還可以將它用作template的參數來用。例如,在TensorRT/parsers/caffe/caffeParser/opParsers/opParsers.h中定義了一個unordered_map,其mapped_type為LayerParseFn

nvinfer1::ILayer* parseConvolution(nvinfer1::INetworkDefinition& network, const trtcaffe::LayerParameter& msg, CaffeWeightFactory& weightFactory, BlobNameToTensor& tensors);
//...

static std::unordered_map<std::string, LayerParseFn> gParseTable 
{
    {"Convolution", parseConvolution},
    {"Pooling", parsePooling},
    {"InnerProduct", parseInnerProduct},
    {"ReLU", parseReLU},
    {"Softmax", parseSoftMax},
    {"SoftmaxWithLoss", parseSoftMax},
    {"LRN", parseLRN},
    {"Power", parsePower},
    {"Eltwise", parseEltwise},
    {"Concat", parseConcat},
    {"Deconvolution", parseDeconvolution},
    {"Sigmoid", parseSigmoid},
    {"TanH", parseTanH},
    {"BatchNorm", parseBatchNormalization},
    {"Scale", parseScale},
    {"Crop", parseCrop},
    {"Reduction", parseReduction},
    {"Reshape", parseReshape},
    {"Permute", parsePermute},
    {"ELU", parseELU},
    {"BNLL", parseBNLL},
    {"Clip", parseClip},
    {"AbsVal", parseAbsVal},
    {"PReLU", parsePReLU}
};

TensorRT/parsers/caffe/caffeParser/caffeParser.cpp中的CaffeParser::parse則如此使用gParseTable

auto v = gParseTable.find(layerMsg.type());

if (v == gParseTable.end())
{
    //...
}
else
{
    ILayer* layer = (*v->second)(network, layerMsg, weights, *static_cast<BlobNameToTensor*>(mBlobNameToTensor));
    //...
}

此處的*v->second是為LayerParseFn型別的函數,因此我們可以傳參數進去,也可以期待它回傳一個ILayer*型別的值出來。

參考連結

Function Pointer in C

Typedef function pointer?

Function passed as template argument

cpp-code-snippets/function_pointer.cpp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值