vector容器at访问报错以及operator[]

初始化3个int型大小的元素,不清空,at正常访问

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> v(3);
	//v.clear();
	v.at(1) = 10;
	cout << v[0] << ":" << v[1] << ":" << v[2];
	return 0;
}

初始化大小为3个int型的元素,如果清空后,v.size()为0
此时使用at访问会报错,错误如下:越界。this->size()为0,此时使用了1

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> v(3);
	v.clear();
	v.at(1) = 10;
	return 0;
}
root@fd:~/work/test# vim vec.cpp
root@fd:~/work/test# g++ vec.cpp -o vec
root@fd:~/work/test# ./vec 
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 1) >= this->size() (which is 0)
已放弃
root@fd:~/work/test# rm vec
root@fd:~/work/test# vim vec.cpp 
root@fd:~/work/test# !g
g++ vec.cpp -o vec
root@fd:~/work/test# ./vec 
0:10:0

初始化3个int型大小的元素,如果清空后,v.size()为0
使用operator[]正常访问,这种行为是危险的

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> v(3);
	v.clear();
	cout << v[0] << ":" << v[1] << ":" <<  v[2] << endl;
	return 0;
}
root@fd:~/work/test# !g
g++ vec.cpp -o vec
root@fd:~/work/test# ./vec 
0:0:0
root@fd:~/work/test# 

可以看到vector容器中的at方法使用时会检查边界,如果传入的索引大于等于this->size(),即抛出异常,这里的this->size()为0,那么clear之后肯定会报错(注意这里的边界检查并不是说超过了容量的大小,而是size的大小)

const_reference at(size_type __n) const
{
	_M_range_check(__n);
	return (*this)[__n];
}

void _M_range_check(size_type __n) const
{
	if (__n >= this->size())
	  __throw_out_of_range_fmt(__N("vector::_M_range_check: __n "
				       "(which is %zu) >= this->size() "
				       "(which is %zu)"),
				   __n, this->size());
}

而operator[]显然是不进行边界检查的,这个操作相对于at来说是危险的

  reference operator[](size_type __n) _GLIBCXX_NOEXCEPT
  { return *(this->_M_impl._M_start + __n); }
### 关于 `std::find` 函数调用错误的原因分析 在 C++ 中,`std::find` 是标准库 `<algorithm>` 提供的一个通用算法,用于在一个范围(由两个迭代器指定)内查找特定值的位置。如果找不到该值,则返回结束迭代器。 #### 错误原因 当使用 `std::find` 时出现 “no matching function for call” 的编译错误,通常是因为传递给它的参数不匹配其模板签名。具体来说: 1. **容器类型与目标值类型的不一致** 如果你在使用 `std::vector<int>::iterator` 和一个整数引用之间调用了 `std::find`,可能会引发此问题。这是因为某些 STL 容器存储的是复杂数据结构而非原始类型,例如 `std::vector<std::string>`. 此时,如果你尝试通过传入一个简单类型 (如 `int&`) 来寻找元素,就会发生类型不匹配的情况[^1]。 2. **引用绑定失败** 当试图将右值赋给左值引用时也会触发类似的错误消息。比如下面的例子中,`value_to_find` 被声明为非常量引用 (`int&`) ,但它被初始化成字面常量 `7`, 这种情况下无法成功创建这样的引用变量从而导致编译期报错: ```cpp int main(){ std::vector<int> vec = {1, 2, 3}; int& value_to_find = 7; // Error: cannot bind non-const lvalue reference to an rvalue. auto it = std::find(vec.begin(), vec.end(), value_to_find); } ``` 为了修正上述代码片段中的问题,可以考虑去掉引用或将引用改为常量引用(`const int&`)来允许它绑定到临时对象上. #### 解决方案 以下是几种常见的解决方案及其适用场景: 1. **确保比较的对象具有相同的类型** 假设我们有一个向量保存字符串并希望找到某个特定的字符串实例: ```cpp #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<std::string> v{"apple", "banana"}; // 使用 const 引用来避免不必要的拷贝操作 const std::string target = "banana"; auto result = std::find(v.begin(), v.end(), target); if(result != v.end()) { std::cout << *result; } } ``` 2. **调整目标值的数据类型** 若确实需要处理基本数值型别的搜寻动作,在确认两者皆为基础资料型态的前提下无需额外转换即可正常运作;然而若是面对较为复杂的自订类别则需自行实现相等性判断逻辑或是利用适配器模式完成任务[^2]. 3. **采用 lambda 表达式作为谓词** 对于那些既不是基础数据类型又缺乏默认比较机制的情形下,我们可以借助 Lambda Expressions 自定义比较规则如下所示: ```cpp struct Person{ std::string name; int age; }; bool operator==(const Person& lhs,const Person& rhs){ return lhs.name==rhs.name && lhs.age == rhs.age ; } int main(){ std::vector<Person> people={{“John”,30},{“Jane”,25}}; Person person_of_interest={"John",30}; auto found=std::find_if(people.begin(),people.end(), [&person_of_interest](const Person &p)->bool{return p==person_of_interest;} ); if(found!=people.end()){ std::cout<<found->name<<" was located."<<std::endl; }else{ std::cout<<"Not Found!"<<std::endl; } } ``` 以上方法能够有效应对大多数因类型差异引起的 `std::find` 编译错误情况。 ### 示例代码 以下是一个完整的例子展示如何正确运用 `std::find` 查找矢量内的元素: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main () { vector<int> numbers = {10, 20, 30, 40, 50}; // Correct usage of std::find with appropriate types int searchValue = 30; vector<int>::iterator position = find(numbers.begin(), numbers.end(), searchValue); if(position != numbers.end()) cout << "Element found at position : " << distance(numbers.begin(),position)+1 << endl; else cout << "Element not found" << endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值