std::for_each易忽略点

std,for,each,忽略 · 浏览次数 : 2

小编点评

代码中使用了`for_each`函数来对vector中的每个元素进行平方操作。但是,由于`for_each`函数默认情况下会将元素的值通过`operator*`传递给回调函数,而`*`运算符在`std::vector`中用于元素的获取,所以最终结果还是与原始元素相同。 以下是代码的详细解释: ```cpp std::vector v1{1, 2, 4, 2}; std::for_each(begin(v1), end(v1), [](auto&n) { return n * n; }); ``` 这段代码将使用`std::for_each`函数对`v1`中的每个元素进行平方操作。`for_each`函数的回调函数接受一个参数`auto&n`,表示当前元素的引用。`n * n`计算元素本身的平方值。 但是,由于`std::vector`中元素的类型是`int`,`n`在平方运算过程中会被转换为`double`类型,导致最终结果与原始元素相同。 **解决方法** 为了让代码得到正确的结果,可以使用以下几种方法: 1. **强制类型转换**: 使用`static_cast(n)`强制转换为`int`类型。 ```cpp std::for_each(begin(v1), end(v1), [](auto&n) { return static_cast(n * n); }); ``` 2. **使用`std::transform`**: 使用`std::transform`将元素的值转换为`int`类型。 ```cpp std::vector v2 = std::transform(v1.begin(), v1.end(), [](int n) { return n * n; }); ``` 3. **使用`std::map`**: 使用`std::map`存储元素,并使用`[]`运算符访问元素的值。 ```cpp std::map m; m[1] = 2; m[4] = 8; std::for_each(m.begin(), m.end(), [](auto&n) { std::cout << n.first << n.second << ' ';}); ```

正文

  以下代码为修改vector内部的每一个元素,使其每个元素大小变为原来的平方。

    std::vector v1{1, 2, 4, 2};

    std::for_each(begin(v1), end(v1), [](auto& n) {
        return n * n;
    });

    for (const auto& item : v1)
        std::cout << item << ' ';

  但是输出结果依旧是1,2,4,2。

 

  在cppreference官网for_each的描述中,有这么一段话:

  For both overloads, if the iterator type (InputIt/ForwardIt) is mutable, f may modify the elements of the range through the dereferenced iterator. If f returns a result, the result is ignored.

  也就是说,有返回值的函数是会被忽略掉的,所以就造成了上面的结果。

  另外一方面,可以看到for_each的实现:

template<class InputIt, class UnaryFunction>
constexpr UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
{
    for (; first != last; ++first)
        f(*first);
 
    return f; // implicit move since C++11
}

  若f是有返回值的函数(可以结合最上面的demo来看),其返回了n的平方而没有实质对n做修改操作,所以最终结果也没有发生变化。

与std::for_each易忽略点相似的内容:

std::for_each易忽略点

以下代码为修改vector内部的每一个元素,使其每个元素大小变为原来的平方。 std::vector v1{1, 2, 4, 2}; std::for_each(begin(v1), end(v1), [](auto& n) { return n * n; }); for (const auto&

何时/如何使用 std::enable_shared_from_this

要点回顾 继承自 std::enable_shared_from_this 的类能够在其自身实例中通过 std::shared_from_this 方法创建一个指向自己的 std::shared_ptr 智能指针。 从一个裸指针创建多个 std::shared_ptr 实例会造成严

std::copy与std::back_inserter引发的惨案

#include #include #include #include int main() { std::vector v{1, 2, 3, 4, 5}; std::copy(begin(v), end(v), std

用现代C++写一个python的简易型list

std::variant介绍:en.cppreference.com/w/cpp/utility/variant 通过泛型模板(仅提供了int, double, string三种类型的存储),实现了append, pop, front, back, size等方法,并且通过重载运算符实现了对负数索引

从优秀源码中学到的两个技巧

设计一个不能被using的对象 在实际开发中为了避免命名空间污染,一般都不会using namespace std。但是如果一个对象写起来比较复杂,用using能大幅度地简化操作。现在假设我们要设计一个函数,它在一个作用域里面,使用它只能以A::B::C()这种形式。思考一下,如果我们放在命名空间下

scanf、cin及其优化、快读性能测试

为了让大家了解C++各种IO方式的性能,于是就有了这篇文章。 本次测试采取的数据均为 \(10^6\) 个不超过 \(10^8\) 随机正整数。 测试代码: #include using namespace std; int x; int main(){ freopen

SDL3 入门(3):三角形

SDL3 提供了 SDL_RenderGeometry 函数绘制几何图形,用法和 OpenGL 差不多,先定义顶点数据,然后根据顶点数据绘制几何图形。 绘制三角形的代码如下: std::array origin_vertices = { SDL_Vertex { { 1

C++11智能指针 unique_ptr、shared_ptr、weak_ptr、循环引用、定制删除器

目录智能指针场景引入 - 为什么需要智能指针?内存泄漏什么是内存泄漏内存泄漏的危害内存泄漏分类如何避免内存泄漏智能指针的使用及原理RAII简易例程智能指针的原理智能指针的拷贝问题智能指针的发展历史std::auto_ptr模拟实现auto_ptr例程:这种方案存在的问题:Boost库中的智能指针un

迭代器的一些简单理解

迭代器的一些简单理解 使用迭代器最方便的地方就是和算法库结合,对于实现只需要聚焦于算法,而不用过多考虑数据结构的实现。 举一个常见的的例子,std::copy_n 用作于范围元素的复制,适配于各个容器类型,并且演化出了 back_inserter/front_inserter/inserter 这类

题解:CF1956A Nene's Game

这道题其实挺有意思,多测里面还套了个多测。 思路就是用向量模拟删除过程,具体请看代码里的注释。 #include using namespace std; int k,q,a[105]; void solve() { int n; cin>>n; vector