2017-07-06 174 views
0

在克++爲常量性病,元件接入操作者::矢量<>被定義爲如下:(/usr/include/c++/7.1.1/bits/stl_vector.hC++ - 爲什麼std :: vector <> :: const_reference可以強制轉換爲非const指針?

/** 
    * @brief Subscript access to the data contained in the %vector. 
    * @param __n The index of the element for which data should be 
    * accessed. 
    * @return Read-only (constant) reference to data. 
    * 
    * This operator allows for easy, array-style, data access. 
    * Note that data access with this operator is unchecked and 
    * out_of_range lookups are not defined. (For checked lookups 
    * see at().) 
    */ 
    const_reference 
    operator[](size_type __n) const _GLIBCXX_NOEXCEPT 
    { 
__glibcxx_requires_subscript(__n); 
return *(this->_M_impl._M_start + __n); 
    } 

但下面的代碼編譯使用g++ -c const-vector.cpp -Wall -pedantic

#include <vector> 

void sum(const std::vector<int>& data){ 
    int *ptr; 
    ptr = (int*) &data[0]; 
    if (data.size()>2) 
    for (unsigned int i=1;i<data.size();i++) 
     ptr[0]+=ptr[i]; 
return;} 

所以我沒有問題改變通過const引用傳遞的vector的內容。

根據cppreference.comoperator[]超載:

reference  operator[](size_type pos); 
const_reference operator[](size_type pos) const; 

在這種情況下,編譯器將採取第二過載?

+3

1.你可以用casts做很多危險的事情,2.修改const引用傳遞的東西本身並不是一個問題。如果你真的把一個const對象傳遞給這個函數,這隻會是一個問題。 –

+0

另外你的代碼將是UB,如果通過一個空的矢量 –

+2

經典c演員是一個大錘 - 它會做你所說的任何事情。看看static_cast發生了什麼 – pm100

回答

1

從「螺絲刀」到「臺鋸」的範圍內,C-style cast是迫擊炮罷工。

當遇到C樣式轉換表達,該編譯器試圖將其解釋爲下面的轉換表達式,以該順序:
一個)const_cast<new_type>(expression);
b)static_cast<new_type>(expression),擴展名爲[...];
c)static_cast(帶擴展名)後跟const_cast;
d)reinterpret_cast<new_type>(expression);
e)reinterpret_cast其次是const_cast

它會逐字地堆積越來越危險的劇組,直到類型系統彎曲和/或什麼東西壞了。只有當你確實絕對需要禁用你可以執行超出語言正常規則的操作的安全性時,你才應該使用它。在這種情況下,你必須確切地知道你在做什麼,並且犯一個錯誤幾乎總會觸發UB而沒有診斷(因爲你只是告訴編譯器閉嘴並且信任你)。

強制修改未知的const對象並不是一個好主意 - 除非您能證明它最初被聲明爲非const,否則您將轉到UB-land。

相關問題