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

为什么std::string的back()应该返回对char的引用?

std::string的back()函数应该返回对char的引用,而不是char本身,有以下几个原因:

  1. 引用返回类型:返回对char的引用可以允许我们修改字符串中的最后一个字符。如果back()返回char本身,我们将无法修改字符串的最后一个字符。
  2. 避免不必要的复制:返回对char的引用可以避免不必要的字符复制。如果back()返回char本身,每次调用back()都会复制一个新的char值,这样会增加额外的开销。
  3. 与其他容器的一致性:std::string是C++标准库中的一个容器,与其他容器(如std::vector)一致性是很重要的。其他容器的back()函数也返回对元素的引用,因此std::string的back()函数也应该返回对char的引用,以保持一致性。
  4. 方便的修改最后一个字符:返回对char的引用可以方便地修改字符串的最后一个字符。我们可以直接通过修改返回的引用来改变字符串的最后一个字符,而不需要使用其他函数或迭代器。

总结起来,std::string的back()函数应该返回对char的引用,以便于修改字符串的最后一个字符,并且避免不必要的复制。

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

相关·内容

网页里返回应该用 history.back 还是 push ?

这就诞生了新问题:如果一个列表页A来源,不止初始页面H,还有多个页面可以跳转列表页A,那么列表页A网页「返回」按钮,应该返回到哪里呢?...网页里返回」按钮(back),只允许相邻页面层级,从右往左返回。对于同一页面层级跳转:可以限制,必须先返回某结点父结点,再进入该结点兄弟结点。...4.3 为什么这样定义产品原则?产品原则目标:让浏览器历史记录栈与网页结构保持一致:用户进入更深页面层级,浏览器历史记录栈就增1。用户返回更浅页面层级,浏览器历史记录栈就减1。...使网页「返回」按钮具有唯一目的地。但网页「返回」按钮还有个问题必须解决:若浏览器当前历史记录栈为空,或历史记录栈上个页面并非该网页页面,点「返回」,应该也能返回父页面。...一些想法只要你页面里,没有「返回」按钮,那啥事都没有 如果你页面,不追求移动端极致用户体验,那也没啥事,PC端用户原生「返回依赖没那么重,你想剥夺就剥夺吧 而我要做移动端页面,有些情况下,原生

5.1K61

日更系列:STD容器push_back为什么会比[]慢

最近在分析算子火焰图数据,发现了比较多std::vector::push_back操作,想着这里是否也可以优化一把。 截屏2021-12-26 下午9.15.04.png 必须了解几个事实。...STL vector另一个棘手问题是有很多方法可以构建。可以用 new或者push_back。 那么这些有啥区别呢?...而且这里即时用reserver保留了空间,push_back也会进行额外条件检查,而这种检查是operator[]不会有的。...简而言之,push_back比做多operator[]——这就是为什么它更慢(更准确)。...在预先知道要插入元素数量前,事先做resize操作,然后使用operator[]。当然并不能说一定能达到明显系统优化,但是至少这个函数来说,有改进了一些。

1K10
  • 一文入魂:妈妈再也不用担心我不懂C++移动语义了!

    二、移动语义实现 在了解了为什么要有移动语义之后,接着我们就该来看看它该如何实现。 (一)左值引用与右值引用 在学习如何实现移动语义之前,我们需要先了解2个概念,即“左值引用”与“右值引用”。...}}; 通过传递左值引用或右值引用,我们就能够根据需要调用不同push_back重载函数了。...int val; std::string str;}; 了解编译器自动生成移动构造函数以及移动赋值运算符之后,我们就会对何时应该自己去实现有个很清晰认识。...但通常来说,我们应该尽可能贴近C++标准库中类型规范。但不管如何,以下这一点是我们必须考虑: 保证被移动对象能够被正确析构。 为什么必须保证这一点呢?...同时,遗憾是,由于std::move(A)返回类型是MyClass&&,与函数返回类型MyClass不一致,因此编译器也不会使用NRVO。

    1.2K20

    深入解析C++右值引用和移动语义:编写更快、更节省内存代码

    因此可以指向右值,这也是为什么要使用 const & 作为函数参数原因之一,如 std::vector push_back 。...从表达式 int &&ref = std::move(a) 来看,右值引用 ref 指向必须是右值,所以move返回 int && 是个右值。所以右值引用既可能是左值,又可能是右值吗?...这同样也符合前面章节左值,右值判定方式:其实引用和普通变量是一样, int &&ref = std::move(a) 和 int a = 5 没有什么区别,等号左边就是左值,右边就是右值。...从移动构造函数实现中可以看到,它参数是一个右值引用类型参数 A&&,这里没有深拷贝,只有浅拷贝,这样就避免了临时对象深拷贝,提高了性能。...source: World有了右值引用和转移语义,我们在设计和实现类时,对于需要动态申请大量资源类,应该设计右值引用拷贝构造函数和赋值函数,以提高应用程序效率。

    3300

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

    右值引用就是右值引用,给右值取别名。...(s1); func2(s1); // string operator+=(char ch) 传值返回存在深拷贝 // string& operator+=(char...下面我们画图分析一下: 实质上,右值被右值引用引用以后属性是左值,即上图中,to_string 返回值是右值,所以会匹配右值引用 push_back 版本,但是在 push_back 中,x 属性却是左值...那么为什么右值被右值引用引用以后属性是左值呢?...其实我们已经接触过了,上面的 push_back 问题就可以使用完美转发解决,我们将 move 改成完美转发形式,并且推荐使用完美转发形式,如下图: 总结:右值引用移动语义出来以后,深拷贝影响比较大

    18110

    现代C++之容器

    1.string string 是模板 basic_string 对于 char 类型特化,可以认为是一个只存放字符 char 类型数据容器。...反过来,如果实现较为复杂、希望使用 string 成员函数的话,那就应该考虑下面的策略: 如果不修改字符串内容,使用 const string& 或 C++17 string_view 作为参数类型...因此,调用这个函数之后,就可以引用容器内对象了。因此当加入新元素时,用operator[]操作符,或者用迭代器来引用元素对象。此时再调用push_back()函数,是加在这个新空间后面的。...4.queue与stack (1)为什么 stack(或 queue) pop 函数返回类型为 void,而不是直接返回容器 top(或 front)成员?...我们有三个可以考虑选项: 如果数组较大的话,应该考虑 vector。vector 有最大灵活性和不错性能。 对于字符串数组,当然应该考虑 string

    1K10

    【C++11】右值引用和移动语义

    返回值是传递进来参数右值引用 move只是返回值为右值引用,并不会真正改变参数属性。它作用是告诉编译器,我们希望该对象执行移动操作,以便能够使用移动构造函数或移动赋值运算符。...C++11中,std::move()函数位于头文件中,该函数名字具有迷惑性,它并不搬移任何东西,唯一功能就是返回参数右值引用(并不会真正改变参数属性),然后实现移动语义。...现在我把移动构造放开(注释取消掉) 那这里编译器肯定优化了,应该是这样 那大家看,不考虑优化的话: 首先to_string返回str,str是一个局部对象(在函数里面str肯定是一个左值...,那相信经过上一篇文章学习,大家应该就能猜出来它作用了 我们来分析一下: 我们给出这样一个场景: 大家看这两个Push_back有什么区别?...第二个插入是move(s1),那move返回是s1右值引用,所以这里就会调第二个右值引用版本push_back

    15410

    C++核心准则-F.48 不要返回使用std:move从局部变量获得右值引用

    F.48: Don't return std::move(local) F.48 不要返回使用std:move从局部变量获得右值引用 Reason(原因) With guaranteed copy...目前,为了保证省略拷贝动作,在返回语句中显式使用std::move差不多是最差方式了。 译者注:copy elision称为拷贝省略或者译作“省略不必要拷贝”,是很重要优化技术。...Example, bad(反面示例) S f() { S result; return std::move(result); } 译者注:使用std::move强制回避拷贝动作做法是不被推荐...Example, good(良好示例) S f() { S result; return result; } 译者注:后一种写法利用了返回值优化(Return value optimization...这个准则应该强制实施并进行工具化检查。 觉得本文有帮助?请分享给更多人 关注【面向对象思考】,每天前进一小步 有任何疑问,欢迎留言提问或讨论 ---- 面向对象设计,面向对象编程,面向对象思考!

    2.1K10

    标准关联容器一定比vector查找速度快吗?

    = sssp.end(); ++i) { std::cout<<"2: "<<**i<<std::endl; } //打印2:需要知道怎么在打印 string* 之前它们解引用,然后后for_each...// DereferenceLess 适合作为 T* 关联容器,也可以作为T对象迭代器和智能指针比较类型 条款18:永远让比较函数相等返回false //1 std::set<int...作为比较类型破坏了容器,并且: //任何相等返回true比较函数都会做同样事情 //因此,你需要确保你用在关联容器上比较函数总是相等返回false struct StringPtrGreater...里,它关联值被更新成V /** 原理如下: 1,operator[]返回一个与 k关联值对象引用,然后 v赋值给所引用 (从 operator[]返回对象 2,当要更新一个已存在关联值时很直接...返回这个新建立对象引用 所以,下面实现等价于 如1-1 */ //1-1 //m[1]是 m.operato简化,所以这是一个 map::operator[]调用,必须返回一个WidgetA引用

    1.8K10

    为什么应该公开用来同步加锁对象?为什么应该 lock(this)lock(string) 或者 lock 任何非私有对象?

    如果你编写线程安全代码时为了省事儿直接 lock(this),或者早已听说不应该 lock(this),只是不知道原因,那么阅读本文可以帮助你了解原因。...---- 原因 不应该 lock(this) 是因为你永远不知道别人会如何使用你对象,永远不知道别人会在哪里加锁。于是稍不注意就可能死锁! 实例 看看下面的两段代码。...第一段是定义好一个类,其中某个方法为了线程安全加了锁,但加锁是 this 对象。...—— 死锁 在 DouB_Walterlv 方法中完全看不出来为什么死锁,只能进入到 DoSafety 中才发现试图 lock this 对象刚刚在另一个线程被 lock (_foo) 了。...如果你试图实现某些接口中 SyncRoot 属性,却遇到了上述矛盾(这样写法不安全),那么可以阅读我另一篇博客了解如何实现这样“有问题”接口: 为什么实现 .NET ICollection

    50610

    【C++11】万能引用与完美转发

    为什么全部匹配都是左值引用啊! 那这里为什么会这样呢?...那再回过头来看我们上面的问题,大家就应该明白了 即使我们传过去是右值,那它被右值引用之后也会变成左值,所以里面再传给Fun都匹配是左值。...那我们把string移动构造和移动拷贝放出来,然后我给listpush_back增加右值引用版本 但是我们push_back复用了insert,所以insert也增加右值引用版本...在第一次传递给push_back 参数,右值的话就调用右值引用版本push_back ,但是push_back里面调用insert第二次传递,就变成左值了 所以最终不论是右值还是左值push_back...operator+=(char ch) string& operator+=(char ch) { push_back(ch); return *this; } string

    17110

    C++惯用法之消除垃圾收集器-资源获取即初始化方法(RAII)

    在现实生活中,你不应该直接写字节数,而应该使用sizeof函数。类似地,我们将char *数组精确地分配给我们需要字符串大小两倍(比字符串长度多一倍,以说明空终止),这是一个相当昂贵操作。...让我们其进行优化,只返回一个指针。...不幸是,随着程序扩展到上述范围之外,很快就变得更加难以推理指针应该在何时何地被删除。当一个函数返回指针时,你现在拥有它吗?您应该在完成后自己删除它,还是它属于某个稍后将被一次性释放数据结构?...来自C ++标准库使用RAII示例为std :: stringstd :: vector。...考虑这段代码: void fn(const std::string& str) { std::vector vec; for (auto c : str) vec.push_back

    89020

    多线程;顺序容器;智能指针

    ,在每个线程内部都有互斥锁操作防止两个线程运行时相同数据进行干扰 互斥锁mutex是用来保证线程同步,防止不同线程同时操作同一个共享数据 通过mutex可以方便临界区域加锁,std::mutex...使用 size()返回容器中元素数目; swap()交换两个容器内容; begin()返回一个指向容器中第一个元素迭代器; end()返回一个表示超过容器尾迭代器(指向容器最后一个元素后面的那个元素位置...*/ /* 如果从小到大应该改为"v1 < v2" */ } void test() { deque<int> d; d.push_back...<string> names; vector<const char*> oldstyle = { "I","love","you" }; //names = oldstyle;错误...例如,调用make_shared时传递参数必须与string某个构造函数相匹配。如果不传递任何参数,对象就会进行值初始化。

    10110

    C++11

    int main() { //发生函数嵌套引用时候,如果每个函数里面代码太多,此时并不能直接知道函数返回类型 // 使用迭代器遍历容器, 迭代器类型太繁琐 std::map<std...运行结果为: 是不是懵逼了,按理来说应该是移动构造才,怎么是深拷贝呢? 就是因为我们在push_back右值引用版本之后,我们属性已经变成了左值,所以以后一直照着左值版本运行。...int main() { std::list > mylist; // emplace_back支持可变参数,拿到构建pair对象参数后自己去创建对象...std::list > mylist; mylist.emplace_back(10, "sort"); mylist.emplace_back...->returntype:返回值类型。用追踪返回类型形式声明函数返回值类型,没有返回 值时此部分可省略。返回值类型明确情况下,也可省略,由编译器返回类型进行推导。

    11910

    【C++修炼之路】27.右值引用

    右值引用就是右值引用,给右值取别名。 函数返回值指的是传值返回。之前提到过,在调用函数之后会销毁函数栈帧,会生成一个临时对象拷贝函数返回值,这个临时变量之所以有常性就是因为其是右值。.../int&& r2 = a;//error // 右值引用可以引用move以后左值 int&& r3 = std::move(a); return 0; } 二.引用返回意义 在了解右值引用之前...operator+=(char ch) string& operator+=(char ch) { push_back(ch); return *this; } const char*...六.const修饰右值引用 6.1 右值引用变量属性 我们知道,左值引用可以修改,const修饰左值引用不能修改。但是对于右值引用来说,右值本身就不能修改,为什么还要加上const呢?...int main() { std::list lt; cfy::string s1("11111"); lt.push_back(std::move(s1)); lt.push_back

    26400
    领券