首页
学习
活动
专区
工具
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的实现方式导致其元素以值传递的方式进行复制。

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

相关·内容

列表初始化:轻量级对象initializer_list

Date d4 = 2025;:C++98中允许的隐式类型转换,调用Date(int, int, int)构造函数,剩余参数使用默认值。...例如,要初始化一个std::vector对象并赋予多个初始值,可能需要多次调用push_back,或者手动实现多个构造函数来支持不同数量的参数。...的列表初始化:通过{}直接传入初始值列表,调用了接受std::initializer_list的构造函数。...return 0; } 接受std::initializer_list的构造函数:在自定义类MyClass中,定义了一个构造函数,接受std::initializer_listint>类型的参数。...调用函数时传入列表:在调用printValues时,直接传入一个初始化列表{10, 20, 30, 40, 50},也可以作为构造函数或拷贝构造函数等的实参进行传入。

28310

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

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

22810
  • 【深度剖析 C++11】 第一弹:现代 C++ 编程的基石与革新

    下面我们来看一下initializer_list构造的使用 void Test_initializer_list() { //v1是直接调用vector的initializer_list构造 vector...左值引用已经解决大多数场景的拷贝效率问题,但是还是存在一些场景无法解决,这里简单模拟实现了一个使用字符串进行数字加减的函数,无法使用左值引用返回,因为str是一个局部对象,函数调用结束后,会随着函数栈帧一起销毁...即在函数的形参列表加上需要返回类型的引用对象,在函数外部创建好对象,以左值引用的方式传入,在函数内部修改,最后作为返回值返回,因为传参的是引用,确实解决了拷贝的问题,但是这样的使用还是让我们很不舒服。...vs2019 前两个构造函数是分别用 "123" 和 "456"来构造zwy::string对象作为函数的实参,第三个构造函数是函数内部的临时对象string str的构造,第四个移动构造就是用str是右值作为移动构造的参数来构造...,会作为右值移动构造ret 直接合二为一 优化为一个对象,在函数内部直接构造。

    4400

    初识C++ · C++11(1)

    前言: 在C++11之前,C++98的出现使得C++看起来更像是一门独立的语言,C++委员会成立后,对外宣称的是5年一个版本,但是呢,计划赶不上变化,03年发布了C++03,计划07年发布07版本,变数多了...1 统一列表初始化 初始化列表在我们前面vector的时候就有所涉及了,但是当时我们介绍的不是那么深入,介绍了数组赋值的那个花括号里面的叫做initializer_list,在C++11版本支持这种自定义的赋值...提到了列表初始化,就不得不提到initializer_list了,这里以vector为例子: 在C++11的版本,支持initializer_list的构造,这样对于对象的创建就更加简单了。...2.4 stl的部分变化 在C++11中引入了多个新的容器,比如array,forward_list,unordered_map,unordered_set,以及对于容器的构造函数等插入了新的函数重载,...因为右值引用的本质是左值,这个就很坑了,比如模拟实现的list,明明用的是右值,push_back的时候,调用了insert,但是传给insert的参数看起来是右值,但是本质的属性还是左值,就又会到左值的函数那里

    7510

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

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

    82140

    C++奇迹之旅:列表初始化和std::initializer_list(C++11第一篇)

    C++ 03的下一个版本的时候,一开始计划是2007年发布,所以最初这个标准叫C++ 07。...统一的列表初始化 {}初始化 在C++98中,标准允许使用花括号{}对数组或者结构体元素进行统一的列表初始值设定。...; return 0; } 创建对象时也可以使用列表初始化方式调用构造函数初始化 struct Point { int _x; int _y; }; class Date { public: Date...一般是作为构造函数的参数,C++11对STL中的不少容器就增加std::initializer_list作为参数的构造函数,这样初始化容器对象就更方便了。...} 列表中可以有任意多个值 vectorint> v1 = { 2024,8,26,20,56 }; vectorint> v2({ 2024,8,26,20,56 }); std::initializer_list

    10410

    C++11『基础新特性』

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

    31140

    【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成员函数访问元素时采用抛出异常检查。

    21220

    【c++11】列表初始化与声明

    int* pa = new int[4] { 0 }; return 0; } 创建对象时也可以使用列表初始化方式调用构造函数初始化 class Date { public: Date(int year..., 1, 1); // old style // C++11支持的列表初始化,这里会调用构造函数初始化 Date d2{ 2025, 1, 2 }; Date d3 = { 2025, 1, 3...它的主要特点包括: 表示一组常量值的不可变数组(只读的顺序容器)。 提供对数组元素的访问,但不能修改其中的值。 由编译器隐式生成,用户无需直接构造 initializer_list 对象。 2....使用示例 (1)用于函数参数 一个函数可以接受 std::initializer_list 参数,从而支持传入多个值作为初始化列表: #include initializer_list> #include...std::cout << w << std::endl; // 输出 5.5 return 0; } (3)用在函数返回类型 在函数返回类型中,可以使用 decltype 推导返回值的类型

    13510

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

    public: vector() {} // 编译器会自动调用默认初始化列表 }; 2. 带参构造函数 通过给定的数量和值来初始化vector。...); } } 当vectorint>(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

    15010

    【C++】C++11风云再起:语法新纪元,性能新巅峰!

    initializer_list版本的构造 vectorint> v1({ 1,2,3,4 }); //列表初始化,构造临时对象,再拷贝构造,但编译器会直接优化成构造(=可以省略) vectorint...,增强灵活性 使用场景 函数参数 任意对象的初始化 实现机制 内部通过临时数组存储 直接调用构造函数 修改性 不可修改 支持修改 2.可变模板参数 可变参数模板是C++11引入的一种强大的模板功能,允许模板...main() { PrintArgs(1, 2.5, "Hello", 'A'); return 0; } emplace系列接口 在C++11后, C++中的标准容器(如 vector 、deque...这样,emplace 能够根据传入参数的具体类型(左值或右值)正确调用匹配的构造函数。...emplace_back :直接将构造临时对象 piar 的参数传入,在函数内部,通过参数包的层层传入,最终在插入的目标位置调用 pair 的构造函数构造出 pair ,从而避免了不必要的拷贝/移动操作

    5810

    【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在原来的基础上新增了两个默认成员函数:移动构造函数和移动赋值运算符重载 关于这两个函数需要注意: 如果你没有自己实现移动构造函数,且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任...默认生成的移动构造函数,对于内置类 型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造, 如果实现了就调用移动构造,没有实现就调用拷贝构造。

    10610

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

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

    17310

    C++11(1)

    C++11优势 C++11是继1998年的后更新的C++大版本;C++11对比C++98带来了数量可观的变化,增加了很多新特性。...这两个{}本质上是不一样的,date d的{}会调用它的构造函数初始化d,而date类中只有三个参数,所以{}中只能有3个数;但是vector就不一样了,vector的{}中的元素数量是可变化的,并不是固定的三个...的介绍文档: https://cplusplus.com/reference/initializer_list/initializer_list/ 在vector和list的底层实现拷贝构造时也使用到了...排序"} }; 分析:这个mp初始化使用了{}和initializer_list的结合;{"apple","苹果"}等是调用了pair的构造函数,最外层就是initializer_list...:这是在C++文件中的一段代码,两个函数的参数分别是int和int*,当实参是NULL时是可以调用第一个函数的,因为C中define了NULL是0;如果要调用第二个函数是不是就需要传实参为指针类型,我们就需要传参数

    4500

    【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.

    6310

    初始化|这些年踩过的坑

    v2{std::vector{1, 2}}; 在上述代码中v1的值有3个,分别为1 2 3,那么按照该规则,v2的类型岂不是std::vectorvectorint>>,在一开始学习这块的时候...编译器有个特点,对于以花括号初始化的方式则认为是统一初始化,如果构造函数中同样存在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

    23610

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

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

    20320

    C++ STL源码剖析之map、multimap、initializer_list

    3.initializer_list使用 ★实际编程实践 ” vectorint> v={1,2,3}; // 底层调用vector的构造函数 v={2,5,6}; /.../ 底层调用vector的=操作符 initializer_listint> ll={4,5,6}; v.insert(v.begin(),ll); // 底层调用下面insert函数 for(auto...x:v) cout<<x<<" "; cout<<endl; vectorint> vv(ll); // 底层调用vector的构造函数 vector city{"Berlin...但是map没有类似的构造,它也应用在map构造函数,insert与=处,跟上面是一样的,都是三处,哈哈~ 使用initializer_list三处: // map构造 map(initializer_list...在初始化的时候,定义及赋值的时候就直接调用构造,后面再次赋值,就是先调用拷贝构造(有可能会被编译器优化),再调用=操作符。

    1.2K10
    领券