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

为什么不能在`std::initializer_list`中使用引用类型

std::initializer_list中不能使用引用类型的原因是因为std::initializer_list是一个轻量级的容器,它的元素是以值传递的方式进行存储的。当我们使用引用类型作为std::initializer_list的元素类型时,会导致引用的生命周期问题。

引用类型是对某个对象的别名,它并不拥有独立的存储空间。当我们将引用类型的对象添加到std::initializer_list中时,实际上只是将该对象的引用传递给了std::initializer_list,而不是将对象本身复制到容器中。这就意味着,当std::initializer_list被使用时,其中的引用可能已经失效,因为引用所指向的对象可能已经超出了其作用域。

另外,std::initializer_list是一个常量容器,它的元素是不可修改的。而引用类型的对象必须在初始化后就指向某个对象,并且无法重新绑定到其他对象。因此,在std::initializer_list中使用引用类型的元素是没有意义的。

总结起来,不能在std::initializer_list中使用引用类型的原因是:

  1. 引用类型的生命周期问题:引用可能已经失效。
  2. std::initializer_list是常量容器,引用类型的对象无法重新绑定。

腾讯云相关产品和产品介绍链接地址:

腾讯云提供了丰富的云计算产品和服务,包括云服务器、云数据库、云存储等。您可以访问腾讯云官方网站(https://cloud.tencent.com/)了解更多详情。

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

相关·内容

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

类型推导如下进行: 如果expr是左值,T和ParamType都会被推导为左值引用。 第一,这是模板类型推导唯一一种T和ParamType都被推导为引用的情况。...原因在于第2节描述,auto声明变量使用{}初始化时,会被推导为std::initializer_list。...另外,在构造函数有参数情况,若不包含std::initializer_list参数或者 构造未传入实参,()和{}产生一样的效果,否则{}优先匹配std::initializer_list参数的构造函数...要求变窄转换 只有当传入的参数在编译器上无法转换成std::initializer_list的T类型,才会匹配普通的构造函数。...在构造重载匹配,只要参数能够强转std::initializer_list的T,就会匹配std::initializer_list构造函数,即便有更加匹配的构造函数。

17120

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

::initializer_list std::initializer_list 的介绍文档:std::initializer_list 我们先来看看 std::initializer_list 是什么类型的...类型,这是 C++11 新增加的类型,每个容器都增加了使用 initializer_list 的构造函数,数据被识别成 initializer_list 类型后再调用相应的构造函数进行初始化,参考文档...当他们的参数个数匹配的时候,{} 内也会被识别成 initializer_list 类型,这时候由于参数个数匹配会报错!...右值引用使用场景和意义 前面我们可以看到左值引用既可以引用左值和又可以引用右值,那为什么 C++11 还要提出右值引用呢?是不是画蛇添足呢?...完美转发 模板的&& 万能引用: 模板的 && 代表右值引用,而是万能引用,其既能接收左值又能接收右值。

14710

深入解析C++的auto自动类型推导

x2的定义将会引起编译错误,因为x2虽然推导为initializer_list类型,但是在推导T的类型时,里面的元素的类型统一,导致无法推导出T的类型,引起编译错误。...[](int p1, int p2) { return p1 < p2; } 避免对类型硬编码 除了上面提到的可以减少代码的冗余之外,使用auto也可以避免对类型的硬编码,也就是说写死变量的类型,让编译器自动推导...但是上面的代码定义p的类型是前者,这会导致编译器想尽办法来将m的元素(类型std::pair)转换成std::pair<std::string, int...) { std::cout " << v << std::endl; } 使用auto声明函数的形参(C++20) 之前提到无法在普通函数中使用auto来声明形参,这个功能在...lambda式参数无法使用initializer_list类型 同样地,在lambda式使用auto来声明形参时,也不能给它传递initializer_list类型的参数,如下代码: std::vector

15220

Java如何使用引用数据类型的类呢?

--------------------------------------- Java数据类型的分类:   基本数据类型:4类8种。...注意:字符串、Lambda这两种引用数据类型后面会学习到。 --------------------------------------- Java如何使用引用数据类型的类呢?...在Java 9 或者更早版本,除了8种基本数据类型,其他数据类型都属于引用数据类型。...如果希望使用引用类型的“类”,那么典型用法的一般步骤为: 例如:使用JavaJDK已经写好的扫描器类 Scanner。 步骤1:导包。     指定需要使用的目标在什么位置。...引用数据类型一般需要创建对象才能使用,格式为: 数据类型 变量名称 = new 数据类型(); 例如:       Scanner sc = new Scanner(System.in);

3.2K10

Effective Modern C++翻译(3)-条款2:明白auto类型推导

//同上 这是由于auto类型推导的一个特殊的规则,当变量使用大括号的初始化式(braced initializer)初始化的时候,被推导出的类型std::initializer_list,如果这个类型不能被推导出来...无法推导出std::initializer_listT的类型 就像注释里指出的的那样,类型推导在这种情况下失败了,但是,重要的是认识到这里其实发生了两种形式的类型推导,一种来源于auto的使用...,但是规则就是规则,这意味着,你必须记住如果你用auto声明一个变量,并且用大括号的初始化式进行初始化的时候,推导出的类型总是std::initializer_list,如果你想更深入的使用统一的集合初始化时.../ std::initializer_list类型 陷阱的主要原因是一些程序员只有当必要的时候,才使用大括号的初始化式进行初始化)(This pitfall is one of the reasons...请记住: auto的类型推导通常和模板类型推导完全相同。 唯一的例外是,当变量用auto声明,并且使用大括号的初始化式初始化时,auto被推导为std::initializer_list

683100

MyBatis 为什么建议使用 where 1=1?

正确的改进方式 其实不用,在 MyBatis 早已经想到了这个问题,我们可以将 SQL 的 where 关键字换成 MyBatis 的 标签,并且给每个 标签内都加上 and 拼接符,这样问题就解决了...传任何参数的请求 此时我们可以传递任何参数(查询所有数据),如下图所示: 生成的 SQL 语句如下: 传递 1 个参数的请求 也可以传递 1 个参数,根据 name 进行查询,如下图所示...SQL 如下图所示: 传递 2 个参数的请求 也可以根据 name 加 password 的方式进行联合查询,如下图所示: 生成的 SQL 如下图所示: 用法解析 我们惊喜的发现,在使用了...标签之后,无论是任何查询场景,传一个或者传多个参数,或者直接传递任何参数,都可以轻松搞定。 ​...and 关键字删除掉,从而不会导致 SQL 语法错误,这一点官方文档也有说明,如下图所示: 总结总结 在 MyBatis ,建议尽量避免使用无意义的 SQL 拼接 where 1=1,我们可以使用

73410

MyBatis 为什么建议使用 where 1=1?

2 正确的改进方式 其实不用,在 MyBatis 早已经想到了这个问题,我们可以将 SQL 的 where 关键字换成 MyBatis 的标签,并且给每个标签内都加上 and 拼接符,这样问题就解决了...传任何参数的请求 此时我们可以传递任何参数(查询所有数据),如下图所示: 生成的 SQL 语句如下: 传递 1 个参数的请求 也可以传递 1 个参数,根据 name 进行查询,如下图所示: 生成的...生成的 SQL 如下图所示: 传递 2 个参数的请求 也可以根据 name 加 password 的方式进行联合查询,如下图所示: 生成的 SQL 如下图所示: 用法解析 我们惊喜的发现,在使用了标签之后...,无论是任何查询场景,传一个或者传多个参数,或者直接传递任何参数,都可以轻松搞定。...and 关键字删除掉,从而不会导致 SQL 语法错误,这一点官方文档也有说明,如下图所示: 3 总结 在 MyBatis ,建议尽量避免使用无意义的 SQL 拼接  where 1=1,我们可以使用标签来替代

57510

【笔记】C++2.0新特性

版本的函数 当使用()进行调用时, 则只能使用普通版本的函数调用 当在构造函数中使用, 代替()但没有指明参数时, 会进行默认构造, 即使是基本类型也会被默认构造为0 initializer_list>; // 随后的调用形如 Foo foo; // 等价于 std::vector> foo; 模板别名能在特定情境下发挥作用...这就是为什么我们不允许改变捕获的变量的值 void operator()(int k) const { std::cout<<k; } }; 复杂点的lambda展开后是下面的样子: // 这里对...C++11提出的右值引用让我们可以利用这些临时变量的内存, 从而降低对象使用的开销 临时变量默认是右值, 但是如果我们需要指定一个左值为右值, 最好的方法是调用std::move(...::move的STL源码实现也能理解了: // forward _Arg as movable // 使用万能引用作为参数来接受任何类型的输入 // 然后区别在返回值, 无论此时输入的类型是什么, 都去除引用后添上右值引用符并返回

87220

Modern c++快速浅析

模板类型推导 模板类型推导中最重要的是弄清它什么时候会抛弃引用,什么时候会抛弃常量性 •template void func(T& param);在这个示例函数,如果传递进是一个...的推导 auto推导具有将大括号初始物转换为std::initializer_list或T类型的数据的能力,而模板类型推导不具备这样的能力 C++14 auto a{ 1, 2, 3 };...// std::initializer_list auto b{ 1 }; // std::initializer_list C++17 auto a{ 1, 2, 3 };...reference,而不是bool auto value2 = result[1];我们能对其做出强转来修复这个问题auto value3 = static_cast(result[2]); [c++为什么不提倡使用...,或者使用捕获指向堆上的指针来自行管理对象的生命周期(或者使用智能指针,注意std::shared_ptr按引用捕获的时候,不会累加引用次数) 但按值捕获也不一定能保证悬垂安全,例如对this指针的捕获

15910

C++11的简单介绍(上)

::initializer_list std::initializer_list的中文翻译就是初始化列表,例如: il就是一个std::initializer_list il = { 10, 20,...; return 0; } 输出结果如下: std::initializer_list使用场景: std::initializer_list一般是作为构造函数的参数,C++11对STL的不少容器就增加...int&& r2 = a;//该语句报错 // 右值引用可以引用move以后的左值 int&& r3 = std::move(a); return 0; } 5.2右值引用使用场景和意义 左值引用使用场景...5.4 完美转发 模板的&& 万能引用 模板的**&&代表右值引用,而是万能引用,其既能接收左值又能接收右值。...); // const 右值 return 0; } 其实完美转发又名折叠引用,因为当引用对象为左值是&就会进行折叠 std::forward 完美转发在传参的过程中保留对象原生类型属性 例如: 下面这段代码在模板没有使用完美转发

8310

【重学 C++】06 | C++该不该使用 explicit

今天,我们来聊聊到底该不该使用explicit 。explicit的作用在C++,默认允许隐式转换,隐式类型转换是指在表达式自动进行的类型转换,无需显式地指定转换操作。...单入参std::initializer_list的构造函数std::initializer_list 是 C++11 引入的一种特殊类型,用于简化在初始化对象时传递初始化列表的过程。...() {MyClass obj = {1, 2, 3, 4, 5}; // 使用初始化列表语法进行隐式转换}对于带有std::initializer_list类型参数的构造函数,也推荐使用explicit...在拷贝构造函数和移动构造函数推荐使用 explicit,以便编译器可以自动调用这些构造函数。...对于带有单入参std::initializer_list的构造函数,也推荐使用explicit,以方便使用初始化列表语法进行隐式转换。同类型的扩展类,为了避免差异化,隐式转换会更合适。

20700

C++11常用的一部分新特性

统一的列表初始化 {}初始化 C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自 定义的类型使用初始化列表时,可添加等号(=),也可不添加。...} 这是initializer_list类型使用文档https://cplusplus.com/reference/initializer_list/initializer_list/...并且这个vector可以利用这个类型进行初始化的。 其实就相当于将initializer_list类型的数据遍历然后push_back()到vector里面。...{"排序","sort"} };//里面的两个小花括号也可以理解为一个pair类型initializer_list数组 声明 auto 这个经常用,自动推导左边对象类型。...int y) {return x > y; };//这个类型编译器认识,但是我们不认识 cout << compare(1, 2) << endl; return 0; } 那么,在外部定义的变量能在

397110

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

下面对于STL容器初始化的方式,实际是使用了C++11新增的一个类,叫做initializer_list,这个类的对象的形式其实就是下面代码赋值符号右边的部分,右边就是initializer_list...除上面那样较为简单的initializer_list使用方法外,向下面这样初始化vector和map对象,同样也可以使用initializer_list...,所以可以看到push_back,insert,list_node等函数在传递右值引用实体时,都需要加move保持其属性依旧为右值,这样才能在层层调用的过程引用实体一直保持为右值。...由于构造函数对内置类型处理,所以C++11在成员变量打了补丁,即允许在类定义的时候,给成员变量缺省值,这个缺省值会在构造函数的初始化列表使用,进行成员变量的初始化。...第一种屏蔽的方式就是逗号表达式,他会在推参数包的过程顺便将arr数组初始化为0,但其实初始化也没有关系,直接推参数包也行。

77540

C++11『基础新特性』

对象的迭代器进行数据遍历,就能轻松获取 initializer_list 对象的数据,所以在 C++11 ,几乎对所有库的容器进行了更新:新增参数类型initializer_list...std::initializer_list& init) { std::initializer_list::iterator it = init.begin(); while (it...的一个静态变量,还是一个迭代器类型,所以编译器直接选择了报错,如果是在 C++11 之前,可能可以成功编译,这是因为检查不严格 要想解决问题就需要使用 typename 关键字,直接告诉编译器:std...vector 类(自己模拟实现的) // 供列表初始化调用 vector(const std::initializer_list& init) { typename std::initializer_list...,默认是不可被修改的,如果想要修改,需要使用 引用类型 获取值 接下来演示使用 范围 for 修改容器的值,并打印进行对比 int main() { // 使用列表初始化 list l

21940

C++ 特性使用建议

2.右值引用 建议:只在定义移动构造函数与移动赋值操作时使用右值引用,区分std::move与std::forward的作用。...如果 i 是迭代器或其他非数值类型,拷贝的代价是比较大的。既然两种自增方式实现的功能一样,为什么总是使用前置自增呢?...使用 sizeof(varname) 是因为当代码变量类型改变时会自动更新。您或许会用 sizeof(type) 处理涉及任何变量的代码,比如处理来自外部或内部的数据格式,这时用变量就不合适了。...C++11 ,若变量被声明成 auto,那它的类型就会被自动匹配成初始化表达式的类型。您可以用 auto 来复制初始化或绑定引用。...,哪怕没有接收 std::initializer_list 的构造函数。

1.6K20

Chapter 1: Deducing Types

, param的类型是const int* 规则: 如果函数调用的表达式,实参是一个引用,那么就忽略掉引用部分 然后把表达式和ParamType进行匹配来确定类型T....//类型std::initializer_list,值是{27} auto x4 {27}; //类型std::initializer_list,值是{27} auto x5 =...); f({11,23,9}); //正确,参数被推导为std::initializer_list C++14允许函数的返回值使用auto来自动声明返回值类型,也允许对lambda表达式的参数使用...Understand decltype C++decltype使用的第一个场景是声明一个函数模板,它的返回值类型依赖于参数类型,常见与std::vector, std::deque 例子1: template...} 上述例子 return ci的类型在推导时会忽略掉引用,结果返回的是一个右值,改进一下 //C++14的做法 template<typename Container, typename Index

56730
领券