首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么initializer_list内部的vector<int>的值在调用构造函数后发生了变化?

在C++中,initializer_list是一种特殊的容器,用于初始化对象。当使用initializer_list初始化一个对象时,编译器会将initializer_list中的元素复制到对象中。

在这个问答内容中,我们讨论的是initializer_list内部的vector<int>的值在调用构造函数后发生了变化的原因。

首先,让我们看一下initializer_list的定义和用法:

代码语言:txt
复制
#include <iostream>
#include <vector>

class MyClass {
public:
    MyClass(std::initializer_list<int> values) {
        for (auto value : values) {
            vec.push_back(value);
        }
    }

    void printValues() {
        for (auto value : vec) {
            std::cout << value << " ";
        }
        std::cout << std::endl;
    }

private:
    std::vector<int> vec;
};

int main() {
    MyClass obj = {1, 2, 3, 4, 5};
    obj.printValues();  // 输出:1 2 3 4 5
    return 0;
}

在上面的代码中,我们定义了一个名为MyClass的类,它接受一个initializer_list<int>作为构造函数的参数。在构造函数中,我们将initializer_list中的值逐个添加到内部的vector<int>中。

当我们创建一个MyClass对象并使用initializer_list初始化它时,构造函数会被调用,并将initializer_list中的值复制到vector<int>中。因此,在调用构造函数后,vector<int>的值会发生变化。

这是因为initializer_list的实现方式决定了它的元素是以值传递的方式进行复制的。在上面的代码中,initializer_list<int>中的元素被复制到了vector<int>中,而不是直接引用initializer_list中的元素。

如果你希望在调用构造函数后,vector<int>的值不发生变化,可以考虑使用引用或指针来存储initializer_list中的元素,而不是复制它们。

总结起来,initializer_list内部的vector<int>的值在调用构造函数后发生变化,是因为initializer_list的实现方式导致其元素以值传递的方式进行复制。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【C++11】{}初始化、std::initializer_list、decltype、STL新增容器

为什么这个东西可以赋值给vector呢? ,大家看红色圈出来部分,C++11给STL中这些容器增加了这样一个构造函数。...支持用initializer_list类型对象去构造vector这些容器。 所以正常使用这个构造应该是这样写: 那我们写成这样 当然也可以,因为构造函数支持隐式类型转换嘛。...它可以构造函数函数参数中以列表形式传递一组。...可以认为它就是一个常量数组,存储常量区,initializer_list对象中元素永远是常量值,我们无法改变initializer_list对象中元素。...实际上C++11更新,容器中增加新方法最实用就是插入接口函数引用版本 那关于这里3、4两点提到引用和移动语义我们后面也会花大量篇幅给大家讲解… 8.

19710

C++11『基础新特性』

其实就是当内置类型使用 { } 初始化时,实际上是调用构造函数进行构造 这就不奇怪了,无非就是让内置类型将 { } 也看做一种特殊构造构造 + 赋值 优化为 直接构造 我们可以通过一个简单...{ 1, 2, 3, 4, 5 }; return 0; } 不止可以初始化五个数,初始化十个乃至一百一千个都是可以,显然此时 列表初始化 调用不是 vector 构造函数,因为它构造函数总不可能重载出...所以对于诸如 vector 这种自定义类型来说,需要把 列表初始化 视作一个类型,然后重载对这个类型参数构造函数就行了,于是 initializer_list 类就诞生了,这是一个模板类,大概长这样... 构造函数就好了,比如这样 重载了 initializer_list 构造函数 ---- 位于 vector 类(自己模拟实现) // 供列表初始化调用 vector(const...简单来说就是 构造即初始化,析构则销毁,利用对象创建时需要调用 构造函数,生命周期结束时会自动调用 析构函数 特性 智能指针 就是一个对象,一个构造时申请资源,析构时释放资源小工具,仅此而已 5.2

26440
  • 【C++】C++11常用特性总结

    例如匿名对象,传返回函数调用返回等,因为匿名对象在其所在代码行执行完毕就会被销毁,并且传返回函数调用实际利用了中间生成一个临时变量将返回从被调用函数栈帧即将销毁时带出,这个临时变量一旦被接收...通过运行结果也可以看出,当wyn::string内部实现了移动构造,list插入数据时,如果插入数据是右new结点调用struct node结点构造函数时,会调用string类移动构造,我们自己实现...知道上面的知识,也就能解释为什么移动构造或移动赋值或右引用版本插入等等接口参数都是普通右引用了,因为这些接口都要对右进行资源移动,也就是改变右引用引用对象,所以右引用时候必须是普通引用...那如果在函数模板内部,要调用Fun函数呢?我们想保证调用时候,依旧可以调用到对应参数类型函数,也就是保持参数属性不变。...sort内部进行排序时候,会依次向后两两比较vector元素,比较时就会用我们传调用对象进行比较,然后给可调用对象传两个vector元素过去,根据比较结果开始进行排序,所以lambda表达式和仿函数对象一样都是可调用对象

    80440

    【C++】C++11——简介|列表初始|简化声明|nullptr与范围for|STL中变化

    }; return 0; } vector和list为什么可以这样子初始化,这就要说到一个新容器了:initializer_list initializer_list 是一个容器,是 C++11...C++11引入initializer_list才支持,而这些容器之所以支持使用列表进行初始化,是因为C++11提供了一个构造函数,以initializer_list为参数 看一下C++11vector...构造: 当用列表对容器进行初始化时,会被认为是initializer_list类型,此时不管有多少个都能够被初始化vector。...而我们之前自己实现vector是无法支持,现在我们可以为之前自己模拟实现vector提供一个构造函数:遍历initializer_list元素,然后push_back进要初始化容器当中:...因为array用一个类对数组做了封装,并且访问array容器中元素时会进行越界检查:用[]访问元素时采用断言,调用at成员函数访问元素时采用抛出异常检查。

    20420

    【C++】深入探索:从零开始模拟实现C++中Vector容器

    public: vector() {} // 编译器会自动调用默认初始化列表 }; 2. 带参构造函数 通过给定数量和来初始化vector。...); } } 当vector(10,1)这样初始化时,传两个类型都是int, 与下面的那个区间构造函数(vector(InputIterator first, InputIterator...(e); } } 5.列表赋值 该构造函数接受一个initializer_list作为参数,并使用该初始化列表中元素来初始化vector对象。...start已经发生了变化,此时返回( _finish - _start) 并不是真正size _finish = tmp + sz; _end_of_storage = tmp + n;...void resize(size_t n, const T& val = T())//调用对应默认构造,int这些内置类型模板出来以后也有了自己构造,如int i = int(1); { if

    13410

    【C++11】C++11新纪元:深入探索右引用与移动语义

    0; } 注意:initializer_list迭代器就是原生指针 std::initializer_list一般是作为构造函数参数,C++11对STL中不少容器就增加 std::initializer_list...也可以作为operator=参数,这样就可以用大括号赋值 我们当初模拟实现这些STL容器时,并没有实现initializer_list,今天我们以vector为例子,实现一下initializer_list...而右则是不可以被取地址临时对象或字面值,它们通常表示计算结果或函数返回临时对象。 右引用是C++11引入一种新类型引用,它通过类型加&&来表示。...新类功能 C++11原来基础上新增了两个默认成员函数:移动构造函数和移动赋值运算符重载 关于这两个函数需要注意: 如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中任...默认生成移动构造函数,对于内置类 型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造, 如果实现了就调用移动构造,没有实现就调用拷贝构造

    8610

    C++奇迹之旅:手写vector模拟实现与你探索vector 容器核心机制与使用技巧

    const T& 表示一个对 T 类型常量引用。使用常量引用可以避免函数内部修改传入,并且通常比传方式更加高效,因为避免了不必要复制操作。...value 是参数名字,它代表了要初始化 vector 中每个元素。 T() 是 T 类型默认构造函数调用。它创建了一个 T 类型对象,并使用默认构造函数来初始化它。...默认参数作用:当构造函数调用而未提供 value 参数时,value 会被初始化为 T(),即一个 T 类型默认。 如果提供了 value 参数,那么构造函数会使用提供,而不是默认。...总结: T() const T& value = T() 中作用是提供一个默认用于初始化 value 参数。这个默认是通过调用 T 类型默认构造函数得到。...这样,构造函数没有提供具体情况下,也能正确地初始化 vector 对象中元素。

    15310

    【C++11】入门基础

    new表达式中 int* pa = new int[4] { 0 }; return 0; } C++11中创建对象时也可以使用列表初始化方式调用构造函数初始化: //日期类 class Date...int main() { Date d1(2022, 1, 1); // old style // C++11支持列表初始化,这里会调用构造函数初始化 Date d2{ 2022, 1, 2...它是C++11引入,它主要目的是不使用显式构造函数情况下,实现统一初始化语法。...::initializer_list一般是作为构造函数参数,C++11对STL中不少容器就增加std::initializer_list作为参数构造函数,这样初始化容器对象就更方便了。...std::initializer_list是一个标准库类型,C++11中引入。它是一个模板类,用于不使用显式构造函数情况下,以统一方式初始化容器或其他对象。 3.

    5010

    初始化|这些年踩过

    v2{std::vector{1, 2}}; 在上述代码中v1有3个,分别为1 2 3,那么按照该规则,v2类型岂不是std::vector>,一开始学习这块时候...编译器有个特点,对于以花括号初始化方式则认为是统一初始化,如果构造函数中同样存在std::initializer_list为参数构造函数,那么则优先调用: class MyClass { public...{ MyClass obj{5, 1.0}; }; 我们可能期望MyClass obj{5, 1.0};调用第一个构造函数(以int和double作为参数构造函数),但由于存在以std::initializer_list...试想一下,如果不涉及缩小转换(例如,第二个构造函数接受 in std::initializer_list,则代码将使用第二个构造函数初始设定项列表中int 5转换为double 5.0...)默默执行,而开发人员则认为它正在使用第一个构造函数,emm,后果不堪设想~~ 在上面提了,编译器会优先调用参数为std::initializer_list构造函数,但是有个例外: class MyClass

    19310

    《Effective Modren C++》 进阶学习(上)

    z(0); // 错误 }; 不可拷贝对象,初始化时不可使用=赋值,但可以使用{}、() std::vector ai1{0}; // 没问题,调用构造函数 std::atomic...另外,构造函数有参数情况中,若不包含std::initializer_list参数或者 构造未传入实参,()和{}产生一样效果,否则{}优先匹配std::initializer_list参数构造函数...w8{std::move(w4)}; // 使用花括号,调用std::initializer_list构造函数 接着上述,使用{}初始化时,只要参数能强转换为initializer_list...构造重载匹配中,只要参数能够强转std::initializer_listT,就会匹配std::initializer_list构造函数,即便有更加匹配构造函数。...其内部实现尽量不要有修改共享资源操作(即尽量不要有修改公共变量操作,否则用锁保护),且内部尽量少调用其他函数,因为被调用函数也可能存在线程不安全风险。 17.

    18420

    C++11简单介绍(上)

    使用场景: std::initializer_list一般是作为构造函数参数,C++11对STL中不少容器就增加std::initializer_list作为参数构造函数,这样初始化容器对象就更方便了...//initializer_list作为vector构造函数参数 vector(initializer_list l) { _start = new T[l.size...不仅仅有移动构造,还有移动赋值: jh::string类中增加移动赋值函数,再去调用jh:to_string(1234),不过这次是将jh::to_string(1234)返回对象赋值给ret1...**然后把这个临时对象做为jh::to_string函数调用返回赋值给ret1,这里调用移动赋值。...: 然而使用完美转发: 可以看到最后一次输出结果不一样,完美转发完美地保留了对象原生类型属性 完美转发实际中使用场景: 如果你使用函数调用其他函数来实现,那么你调用函数也要进行完美转发修饰

    11310

    【C++】C++11中常见语法(上)

    类型,这是 C++11 新增加类型,每个容器都增加了使用 initializer_list 构造函数,数据被识别成 initializer_list 类型调用相应构造函数进行初始化,参考文档:...所以我们如果在以前模拟实现 vector 中使用 initializer_list 去初始化对象时候,是会报错,因为我们以前没有写相应构造函数initializer_list 构造函数也很简单...右引用和移动语义: 首先我们 Young::string 中增加移动构造,移动构造本质是将参数右资源窃取过来,占位已有,那么就不用做深拷贝了,所以它叫做移动构造,就是窃取别人资源来构造自己,为什么可以直接窃取别人资源呢...然后把这个临时对象做为 Young::to_string 函数调用返回赋值给接收 ret,这里调用移动赋值。...默认成员函数 原来 C++ 类中,有 6 个默认成员函数构造函数 析构函数 拷贝构造函数 拷贝赋值重载 取地址重载 const 取地址重载 最后重要是前4个,两个用处不大。

    17310

    C++中五花八门初始化规则

    内置类型默认初始化 Tips:建议初始化每一个内置类型变量,原因在于定义函数内部内置类型变量是未定义,如果试图拷贝或者以其他形式访问此类是一种错误编程行为且很难调试。...定义于任何函数体之外变量会被初始化为0,定义函数内部内置类型变量将不被初始化(uninitialized),一个未被初始化内置类型变量时未定义,如果试图拷贝或以其他形式访问此类将引发错误...定义于任何函数体之外类变量会先进行零初始化再执行默认初始化,定义函数内部类变量会直接执行默认初始化。...class Cat { public: int age; }; int main() { /* 内置类型函数内部默认初始化, 随机 */ int int_array[...如果初始化时使用了花括号但是提供又无法用来列表初始化,那么就考虑用这些调用vector构造函数了。

    2.6K10

    【C++航海王:追寻罗杰编程之路】C++11(一)

    相比于 C++98/03,C++11则带来了数量可观变化,其中包含了约140个新特性,以及对C++03标准中 约600个缺陷修正,这使得C++11更像是从C++98/03中孕育出一种新语言。...2 -> 统一列表初始化 2.1 -> {}初始化 C++98中,标准允许使用花括号{}对数组或者结构体元素进行统一列表初始设定。...fyd p{ 1, 2 }; // C++11中列表初始化也可以适用于new表达式中 int* pa = new int[4]{ 0 }; return 0; } 创建对象时也可以使用列表初始化方式调用构造函数初始化...d1(2024, 4, 1); // C++11支持列表初始化,这里会调用构造函数初始化 Date d2{ 2024, 4, 2 }; Date d3 = { 2024, 4, 3 };...一般是作为构造函数参数,C++11对STL中不少容器就增加 std::initializer_list作为参数构造函数,这样初始化容器对象就更方便了。

    6810

    C++11特性大杂烩

    如果没有实现,那么编译器会走initializer_list构造函数图片vector支持initializer_list初始化和赋值简易代码如下templateclass vector...,每结合一个元素,执行依次循环体,直至容器内所有元素都被结合完为止.不依赖于下标元素,(通用于stl库容器)不需要访问迭代器,透明不需要定义处理函数,简洁图片stl库中一些变化根据C++官网可以查到容器...(x);//move之后可以右引用那好端端有了引用(左引用),为什么还要在C++11提出右引用呢?...,但是报错了,原因是此时捕捉列表捕捉是父作用域变量值拷贝,具有常性无法改变且lambda函数总是一个const函数,可以参数列表加mutable表示取消参数常性添加mutable运行,通过打印查看参数...(部分场景提高效率)包装明确了可调用对象返回和参数类型,更加方便使用。bindstd::bind函数定义头文件中,是一个函数模板,它就像一个函数包装器(适配器)。

    89950

    【C++】————C++11

    return 0; } C++11将所有的容器都支持了initializer_list这样构造函数,所以可以用容器都列表初始化,例如:C++11支持list (initializer_list...容器内部变化 容器内部都支持了initializer_list构造,用来支持列表初始化。 增加了cbegin和cend系列接口,实际中也没什么用。...例如模拟实现to_string函数,只能传返回,进行拷贝构造屏幕中打印“深拷贝”。...s) -- 资源转移" << endl; swap(s); } 将移动构造加入到类中,再运行上面Jared::to_string调用,这里没有调用深拷贝拷贝构造,而是调用了移动构造屏幕中打印资源转移...bind   std::bind函数定义头文件中,是一个函数模板,它就像一个函数包装器,接受一个可调用对象,生成一个新调用对象来“适应”原对象参数列表。

    5910
    领券