范围for循环依赖begin和end函数

范围for循环依赖begin和end函数

/*************************************************************************
    > File Name: range_for_loop.cc
    > Author: hsz
    > Brief:
    > Created Time: Thu 18 Jan 2024 10:17:04 AM CST
 ************************************************************************/

#include <iostream>
#include <initializer_list>

/**
 * @brief 测试范围for循环释放依赖于begin和end函数
 */

template<typename T, std::size_t SIZE>
class MyArray {
public:
    MyArray(const std::initializer_list<T> &arr)
    {
        int32_t size = arr.size() <= SIZE ? arr.size() : SIZE;
        int32_t i = 0;
        for (auto it = arr.begin(); i < size; ++i, ++it) {
            data[i] = *it;
        }
    }

    T& operator[](std::size_t index) {
        return data[index];
    }

    const T& operator[](std::size_t index) const {
        return data[index];
    }

    T* begin() {
        return data;
    }

    T* end() {
        return data + SIZE;
    }

private:
    T data[SIZE];
};

int main() {
    MyArray<int, 5> arr = {1, 2, 3, 4, 5};

    for (const auto& element : arr) {
        std::cout << element << " ";
    }
    std::cout << std::endl;
    return 0;
}

g++ range_for_loop.cc -o range_for_loop
修改begin和end函数名后再次编译,报出以下错误。

range_for_loop.cc: In function ‘int main()’:
range_for_loop.cc:53:32: error: ‘begin’ was not declared in this scope
     for (const auto& element : arr) {
                                ^~~
range_for_loop.cc:53:32: note: suggested alternative:
In file included from /usr/include/c++/7/string:51:0,
                 from /usr/include/c++/7/bits/locale_classes.h:40,
                 from /usr/include/c++/7/bits/ios_base.h:41,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from range_for_loop.cc:8:
/usr/include/c++/7/bits/range_access.h:105:37: note:   ‘std::begin’
   template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);
                                     ^~~~~
range_for_loop.cc:53:32: error: ‘end’ was not declared in this scope
     for (const auto& element : arr) {
                                ^~~
range_for_loop.cc:53:32: note: suggested alternative:
In file included from /usr/include/c++/7/string:51:0,
                 from /usr/include/c++/7/bits/locale_classes.h:40,
                 from /usr/include/c++/7/bits/ios_base.h:41,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/ostream:38,
                 from /usr/include/c++/7/iostream:39,
                 from range_for_loop.cc:8:
/usr/include/c++/7/bits/range_access.h:107:37: note:   ‘std::end’
   template<typename _Tp> const _Tp* end(const valarray<_Tp>&);

进一步思考

无论标准库还是其他库,begin和end函数几乎是用于迭代器的实现,而迭代器又要求使用过程中不能修改原有结构。
所以在范围for循环中,不能删除和插入数据。否则,极易产生崩溃问题。

// 错误示例
std::list<int32_t> get_list()
{
    static std::list<int32_t> ret;
    static int32_t idx = 0;
    ret.push_back(idx);
}

for (const auto &it : get_list())
{
    std::cout << it << "\n";
}

如果需要在循环过程中修改结构,可以自己使用迭代器进行遍历。

std::list<int32_t> intList = {1, 2, 3, 4, 5};
for (auto it = intList.begin(); it != intList.end(); ) {
    std::cout << *it << " ";
    if (3 == (*it)) {
        it = intList.erase(it);
    } else {
        ++it;
    }
}
std::cout << std::endl;

for (const auto &it : intList) {
    std::cout << it << " ";
}
std::cout << std::endl;

范围for循环的变量类型不是iterator

std::list<std::string> strList = {"1", "2", "3", "4", "5"};
for (const auto &it : strList) {
    std::cout << it << ", " << typeid(decltype(it)).name() << "\n";
}
std::cout << std::endl;

输出以下内容

1, NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
2, NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
3, NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
4, NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
5, NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值