auto与iterator的说明和使用

auto和iterator是两个不同的概念,但经常结合使用来简化代码

auto用于自动推导变量的类型,本质上是一个关键字,使用auto的时候,编译器会根据变量的初始化表达式来判断变量的类型,就省略了显示声明的步骤。会在编译期进行类型推导,是一种静态类型,编译器在编译时就会确定变量的类型

iterator(迭代器)用于遍历容器的对象,它会为访问容器的元素提供了一种统一的接口,使得无论是数组、链表还是其他容器,都可以通过类似的方式进行访问。还可以通过迭代器来进行前进后退的操作。

主要为什么把它们放在一起进行说明呢,因为我们在使用迭代器的其实大多数时候没有进行声明。因为C++11引入了自动类型推导(auto)的特性。

【也就是在这里,这两者有了联系】

在遍历容器时,使用 auto 关键字可以让编译器根据迭代器的类型自动确定变量的类型,减少了代码的冗余,也可以确保在使用时明确迭代器的有效范围。

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

int main()
{
    vector<int> myVector = { 1, 2, 66, 3, 789, 5 };

    // 使用 iterator 和 auto 结合
    //这里的it就是iterator,只不过用auto进行了说明,编译器会自行识别的
    for (auto it = myVector.begin(); it != myVector.end(); ++it)
    {
        cout << *it << " ";
    }
    cout << std::endl;

    return 0;
}

在上面的例子里面,我们可以看到auto it.......,auto  被用来自动推导myVector.begin()返回的迭代器的类型,无需显式写出类型信息。我们已经知道了auto的作用,但这个it其实就是一个常用的命名约定,表示iterator,在C++里面it会是一个指向容器元素的指针,it在这里也就是我们的iterator了。


iterator(迭代器)

iterator(迭代器的类型可以是输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器,这些类型的迭代器提供了不同程度的功能和灵活性。

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


int main()
{
    // 创建一个 vector
    vector<int> myVector = { 1, 2, 3, 4, 5 };

    // 使用 begin() 和 end() 迭代器遍历 vector
    cout << "Using begin() and end(): ";
    for (vector<int>::iterator it = myVector.begin(); it != myVector.end(); ++it)
    {
        cout << *it << " ";
    }
     cout <<  endl;

    // 使用 rbegin() 和 rend() 迭代器逆序遍历 vector
     cout << "Using rbegin() and rend(): ";
    for ( vector<int>::reverse_iterator rit = myVector.rbegin(); rit != myVector.rend(); ++rit)
    {
         cout << *rit << " ";
    }
     cout <<  endl;

    // 使用 cbegin() 和 cend() 迭代器遍历 vector,不允许修改元素
     cout << "Using cbegin() and cend(): ";
    for ( vector<int>::const_iterator cit = myVector.cbegin(); cit != myVector.cend(); ++cit) 
    {
         cout << *cit << " ";
    }
     cout <<  endl;

    // 使用 crbegin() 和 crend() 迭代器逆序遍历 vector,不允许修改元素
     cout << "Using crbegin() and crend(): ";
    for ( vector<int>::const_reverse_iterator crit = myVector.crbegin(); crit != myVector.crend(); ++crit)
    {
         cout << *crit << " ";
    }
     cout <<  endl;

    return 0;
}

在里面有很多迭代器函数,像最普通的就是begin和end,begin()就是指向容器第一个元素的迭代器 ,你可能会猜到 end()是指向容器最后一个元素的迭代器, 但事实并非如此,实际上,end()是指向容器最后一个元素的下一个位置的迭代器

带上c就代表只读,不可修改,如果有r就代表逆向读取

他们之间有一些通用的功能:

  • 比较两个迭代器是否相等(==、!=)。
  • 前置和后置递增运算(++)。
  • 读取元素的解引用运算符(*)。只能读元素,也就是解引用只能出现在赋值运算符的右边。
  • 箭头运算符(->),解引用迭代器,并提取对象的成员
 // 使用 auto 进行迭代
    for (auto it = myVector.begin(); it != myVector.end(); ++it) {
        cout << *it << " ";
    }

可以看到上面的代码中的for语句很长,所以在这里auto就可以发挥作用了,自动识别


auto

原理就是根据后面的值,来自己推测前面的类型是什么。auto的作用就是为了简化变量初始化,如果这个变量有一个很长很长的初始化类型,就可以用auto代替。这个在迭代器中得到了很好的运用

注意:

1.用auto声明的变量必须初始化(auto是根据后面的值来推测这个变量的类型,如果后面没有值,自然会报错)

2.函数和模板参数不能被声明为auto(原因同上)

3.因为auto是一个占位符,并不是一个他自己的类型,因此不能用于类型转换或其他一些操作,如sizeof和typeid

4.定义在一个auto序列的变量必须始终推导成同一类型


auto还可以在for语句中被运用


int main(){
    vector<int>v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    for(auto i : v){
        cout<<i<<" ";
    }
    cout<<endl;
    return 0;
}

这里for语句中的判断条件就只有 auto i :v  ,格式是for(auto i : v)

这是一种简化遍历容器元素的语法,被称为范围(range-based)for 循环。

具体含义是:对于容器 v 中的每个元素,将其值赋给变量 i,然后执行循环体。在这个例子中,i 会依次取到 123,并将它们输出到标准输出流 cout 中,每个数字后面加一个空格。

这种语法简化了遍历容器的代码,尤其适用于不需要知道元素索引的情况。对于 vector 这样的顺序容器,范围 for 循环是一种常见的使用方式,使得代码更加简洁易读。


参考文章:

c++ auto基本用法_c++ auto 赋初值-CSDN博客

C++ 迭代器(iterator)超详解+实例演练_c++ iterator-CSDN博客

C++中,使用Boost库发送HTTP POST请求通常涉及到Boost.Asio库,这是一个高性能的异步I/O库。以下是一个简单的步骤说明如何使用Boost.Asio发送POST请求: 1. 首先,确保已经安装了Boost库,特别是Boost.Asio和Boost.Filesystem。如果没有,可以从官网下载并安装。 2. 包含必要的头文件: ```cpp #include <boost/asio.hpp> #include <boost/asio/spawn.hpp> #include <boost/asio/streambuf.hpp> #include <boost/algorithm/hex.hpp> #include <boost/filesystem.hpp> ``` 3. 创建一个异步客户端实例,设置POST数据: ```cpp std::string post_data = "your_post_data"; boost::asio::ip::tcp::resolver resolver(io_service); boost::asio::ip::tcp::resolver::query query("example.com", "http"); boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); ``` 4. 创建异步连接和写入POST数据: ```cpp boost::asio::streambuf request; request << "POST / HTTP/1.1\r\n" << "Host: example.com\r\n" << "Content-Type: application/x-www-form-urlencoded\r\n" << "Content-Length: " << post_data.size() << "\r\n" << "\r\n" << post_data; auto connect_handler = boost::bind(&send_request, io_service, socket_, endpoint_iterator, request, response); auto connect_op = spawn(io_service, connect_handler); ``` 这里`send_request`是一个自定义函数,负责处理连接、写入数据以及接收响应。 5. 处理响应: ```cpp void send_request(boost::asio::io_service& io_service, boost::asio::ip::tcp::socket& socket_, boost::asio::ip::tcp::resolver::iterator endpoint_iterator, boost::asio::streambuf& request, std::string& response) { // 发送请求 boost::asio::async_write(socket_, request, boost::bind(&handle_write, io_service, socket_, endpoint_iterator, request, response, _1, _2)); // 接收响应 boost::asio::async_read_until(socket_, response, "\r\n\r\n", boost::bind(&handle_read, io_service, socket_, endpoint_iterator, response, _1, _2)); } // ...处理完成标志和响应数据的方法(handle_write和handle_read) ``` 6. 最后,在适当的`handle_write`和`handle_read`方法中处理完成标志和响应数据。 注意:这只是一个基础示例,实际使用时可能需要处理异常,并且可能需要更复杂的错误处理和日志记录。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值