C++ const_cast

const_cast

簡介

const_cast只能作用於指標上,它的作用是為指標去除或加上constvolatile關鍵字。

如果我們嘗試將它作用於變數上,則會出現以下錯誤:

error: const_cast to 'int', which is not a reference, pointer-to-object, or
      pointer-to-data-member

與C寫法的比較

與簡單的型別轉換相比,它的優點是更為安全,因為它會檢查轉換前後的資料型別是否一致。查看以下例子:

int val = 1000000;
pc = &val;
std::cout << (char *)(pc) << std::endl; //@B
//error: const_cast from 'const int *' to 'char *' is not allowed
std::cout << *const_cast<char *>(pc) << std::endl;

使用C語言中的寫法來做型別轉換可以轉換成功,但是我們會得到一個沒意義的值@B

使用const_cast則會報錯,通知使用者int*並不能透過const_cast轉換成char*

完整代碼詳見cpp-code-snippets/const_cast.cpp

修改const變數

對於一個指向const變數的const指標,如果使用const_cast把指標的const拿掉,再去修改它,那麼結果將會是未定義的。查看以下例子:

int add10(int* ptr)
{   
    *ptr = *ptr + 10;
    return (*ptr);
}

int val = 10;
const int val2 = 10;
int* p;
const int* pc;
    
pc = &val;
p = const_cast <int *>(pc);
add10(p);
std::cout << std::setw(35) << std::left << "try to add int 10 by 10: " << val << std::endl;

pc = &val2; //指向常數的指標
p = const_cast <int *>(pc);
add10(p);
std::cout << std::setw(35) << std::left << "try to add const int 10 by 10: " << val2 << std::endl;

運行結果為:

try to add int 10 by 10:           20
try to add const int 10 by 10:     10

在第二個實驗中,我們嘗試經由將指向val2pc轉為非const,然後再透過它去修改val2的內容,但是結果如上所示,並不會成功。

完整代碼詳見cpp-code-snippets/const_cast.cpp

TensorRT中的例子

TensorRT/parsers/caffe/caffeWeightFactory/caffeWeightFactory.cpp的函數convert中用到了const_cast

void CaffeWeightFactory::convert(Weights& weights, DataType targetType)
{
    //...
    /**/ convertInternal<float, float16>(const_cast<void**>(&weights.values), weights.count, &mOK);
    //...
    /**/ convertInternal<float16, float>(const_cast<void**>(&weights.values), weights.count, &mOK);
    //...
}

查看convertInternal函數的簽名:

template <typename INPUT, typename OUTPUT>
void* convertInternal(void** ptr, int64_t count, bool* mOK)

還有TensorRT/include/NvInferRuntime.hWeights類別的定義:

class Weights
{
public:
    DataType type;      //!< The type of the weights.
    const void* values; //!< The weight values, in a contiguous array.
    int64_t count;      //!< The number of weights in the array.
};

可以發現:&weights.valuesconst void**型別的,在它前面加上const_cast<void**>是為了要去除const,讓它變成void**型別。如此一來,const_cast<void**>(&weights.values)才能被丟進接受void**參數的convertInternal函數裡面。

參考連結

const_cast in C++ | Type Casting operators

cpp-code-snippets/const_cast.cpp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值