当前位置: 首页 > article >正文

C++函数——fill

在C++中,std::fill 是标准库提供的一个算法适用于几乎所有类型的容器只要这些容器支持迭代器操作。具体来说,std::fill 的适用性取决于容器是否提供了满足其要求的迭代器类型,用于将指定范围内的所有元素设置为某个特定值。它是一个类型安全的操作,非常适合对容器或数组中的元素进行初始化或赋值。

函数原型

std::fill 的函数原型定义在 <algorithm> 头文件中:

#include <algorithm>

template <typename ForwardIterator, typename T>
void fill(ForwardIterator first, ForwardIterator last, const T& value);

参数说明

  1. first:指向目标范围的起始位置的迭代器。

  2. last:指向目标范围的结束位置的迭代器。

  3. value:要赋给目标范围中每个元素的值。

功能

std::fill 会将 [first, last) 范围内的所有元素设置为 value。它会逐个调用元素的赋值操作符(operator=),因此可以安全地用于任意类型(包括基本数据类型、类对象等)。

使用示例

1. 初始化数组
#include <algorithm>
#include <iostream>

int main() {
    int arr[10];
    std::fill(arr, arr + 10, 42);  // 将数组的每个元素设置为 42

    for (int i = 0; i < 10; ++i) {
        std::cout << arr[i] << " ";
    }
    // 输出:42 42 42 42 42 42 42 42 42 42
    return 0;
}
2. 初始化标准库容器
#include <algorithm>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec(10);
    std::fill(vec.begin(), vec.end(), 100);  // 将 vector 的每个元素设置为 100

    for (int i : vec) {
        std::cout << i << " ";
    }
    // 输出:100 100 100 100 100 100 100 100 100 100
    return 0;
}
3. 初始化复杂对象
#include <algorithm>
#include <iostream>

struct Data {
    int a;
    double b;

    Data(int x, double y) : a(x), b(y) {}
};

int main() {
    Data arr[5];
    std::fill(arr, arr + 5, Data(10, 3.14));  // 将数组的每个元素初始化为 Data(10, 3.14)

    for (const auto& d : arr) {
        std::cout << "a: " << d.a << ", b: " << d.b << std::endl;
    }
    // 输出:
    // a: 10, b: 3.14
    // a: 10, b: 3.14
    // ...
    return 0;
}

注意事项

  1. 类型安全

    • std::fill 是类型安全的,它会调用目标元素的赋值操作符,因此可以安全地用于复杂对象。

    • memset 不同,std::fill 不会破坏对象的内部状态。

  2. 迭代器要求

    • std::fill 要求迭代器至少是正向迭代器ForwardIterator),这意味着它支持单向遍历。因此,它适用于数组、std::vectorstd::list 等容器。

  3. 性能

    • std::fill 的性能通常稍逊于 memset,因为它需要逐个调用赋值操作符。但对于复杂对象,这是唯一安全的方式。

  4. std::fill_n 的区别

    • std::fill 操作的是一个范围 [first, last)

    • std::fill_n 操作的是从某个起始位置开始的 n 个元素。例如:

      std::vector<int> vec(10);
      std::fill_n(vec.begin(), 5, 42);  // 从 vec.begin() 开始,填充 5 个元素为 42

总结

std::fill 是一个非常实用的算法,适用于需要对容器或数组中的元素进行初始化或赋值的场景。它完全类型安全,可以安全地用于任意类型,包括复杂对象。在C++中,建议优先使用 std::fill 或其他标准库算法,而不是直接操作内存(如 memset),除非需要高效处理原始内存。

不适用的情况

虽然 std::fill 非常通用,但以下情况可能需要注意:

  1. 容器为空

    • 如果容器为空(begin() == end()),std::fill 不会执行任何操作,但也不会报错。

    std::vector<int> vec;
    std::fill(vec.begin(), vec.end(), 42);  // 无操作
  2. 容器不支持迭代器操作

    • 如果容器不提供迭代器(例如某些自定义容器或非标准库容器),则无法直接使用 std::fill。这种情况下,可能需要手动实现类似的功能。

  3. 元素类型不支持赋值操作

    • 如果容器中的元素类型不支持赋值操作(例如某些不可赋值的类对象),则 std::fill 会报错。

    class NonAssignable {
    public:
        NonAssignable() = default;
        NonAssignable& operator=(const NonAssignable&) = delete;
    };
    
    std::vector<NonAssignable> vec(10);
    std::fill(vec.begin(), vec.end(), NonAssignable());  // 编译错误

总结

std::fill 是一个非常通用的算法,适用于几乎所有支持迭代器操作的容器,包括标准库容器(如 std::vectorstd::arraystd::list 等)和C风格数组。它完全类型安全,可以安全地用于任意类型,包括复杂对象。只要容器提供了正向迭代器,并且元素支持赋值操作,就可以使用 std::fill

在实际使用中,std::fill 是一种非常推荐的方式,因为它符合C++的类型安全原则,并且可以无缝集成到标准库的容器操作中。

 


http://www.kler.cn/a/516568.html

相关文章:

  • 【前端】Hexo 建站指南
  • docker-registry
  • 使用飞桨AI Studio平台训练数据,并进行图像识别分析得牡丹花测试
  • 解锁C# EF/EF Core:从入门到进阶的技术飞跃
  • java 根据前端传回的png图片数组,后端加水印加密码生成pdf,返回给前端
  • simulink入门学习01
  • leetcode刷题记录(八十四)——739. 每日温度
  • 2.2.2 大小写敏感性
  • Facebook广告零支出无消耗:可能原因与解决方法
  • 鞅的定义_
  • Ubuntu二进制部署K8S 1.29.2
  • C语言数组详解:从基础到进阶的全面解析
  • bat批处理删除此电脑左侧及另存为下文档视屏等多余项
  • [java] java基础-字符串篇
  • PyTorch入门 - 为什么选择PyTorch?
  • arcgis for js只显示范围内的天地图,其余部分透明
  • Vue基础(2)
  • 前k个高频元素力扣--347
  • 详解C#中的特性(Attribute)
  • 小游戏源码开发搭建技术栈和服务器配置流程
  • 独立开发者产品日刊:将 Figma 设计转化为全栈应用、对话 PDF生成思维导图、视频转 AI 笔记、AI问答引擎、Mac 应用启动器切换器
  • Python散点统计栅格化
  • 动态规划(路径问题)
  • 安宝特方案 | AR在供应链管理中的应用:提升效率与透明度
  • HTML常用标签
  • Docker基础安装与使用