c ++ - 为什么std :: vector<> :: const_reference可以转换为非const指针?

时间:2017-07-06 23:23:00

标签: c++ gcc vector reference const

在g ++中,const std :: vector<>的元素访问运算符定义如下:(public string SwitchDate(string date) { Debug.Log ("Date IN: Switch " + date); string[] inputSections=date.Split('/'); string ServiceDate=string.Format("{0}/{1}/{2}", inputSections[2], inputSections[0], inputSections[1]); Debug.Log ("Date OUT: Switch " + ServiceDate); return ServiceDate; } string SwitchbackDate(string date) { Debug.Log ("Switchback In: " +date); string[] inputSections=date.Split('/'); string ServiceDate=string.Format("{0}/{1}/{2}",inputSections[1], inputSections[2], inputSections[0]); Debug.Log ("Switchback Out: " + ServiceDate); return ServiceDate; }

/usr/include/c++/7.1.1/bits/stl_vector.h

但是以下代码使用/** * @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

所以我正在改变const引用传递的#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;} 的内容。

根据cppreference.comvector已超载:

operator[]

在哪种情况下编译器会进行第二次重载?

1 个答案:

答案 0 :(得分:1)

在&#34;螺旋桨&#34;的范围内到了桌子上,C-style cast是迫击炮。

  

当遇到C风格的强制转换表达式时,编译器会尝试按以下顺序将其解释为以下强制转换表达式:
  a)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对象并不是一个好主意 - 除非你能证明它最初被宣布为非常数,否则你将离开UB-land。