天道酬勤,学无止境

How to return "not found" when return value is const reference

I have a problem that when I use something like this:

const MyList& my_list = getListForThisRegion(/*region ID, ...*/);

I dont know what to return when no value is found.

My problem is that I would like to have a way to signal (when returning value from getListForThisRegion) "value not found" to the caller. If I was returning a pointer, I could return nullptr, but I don't know how to do it with references. All I can think of is having some static member not_found of type MyList, and returning a reference to it, but it seems ugly.

And yes, I can't return value because lists are "fat" and often used.

EDIT: ton of great answers , but exception is not an acceptable solution because the number of times it would be raised is high (the percentage nbNotFound/nbCalls is high).
EDIT2: regarding boost::optional - how complicated it is to master? I mean does it require some non obvious knowledge (non obvious= something that is not simply knowing the syntax)?

标签

评论

There are two idiomatic ways to handle this:

  • Change your interface to return a type that has the ability to refer to nothing (e.g. a pointer that can be null, an iterator to end).

Or

  • Throw an exception if the item isn't found.

Returning a dummy object is a bit hacky, and you don't gain anything over returning a pointer as you still have to check the result against a special value (null or the dummy object).

How about rewriting the function to take reference to "returnValue" where you put the list to return? Then the function can return boolean value indicating found/ not found.

bool getListForThisRegion(/*region ID, ...*/, MyList& ret_list);

I'd write exception class (hierarchy, if needed) and throw an exception for such case.

I only see two possibilities: either you have a special member in the MyList class declaring that an instance is "null" (not set) or you could throw an exception.

You could follow std::map's lead, and insert a default constructed list into your container, and return a reference to that. Obviously, this depends on there not being a semantic difference between a default list, and a list that isn't there at all.

You can also add a query function that searches for a particular region, and returns true if it has a list, and false otherwise. Then, you can throw an exception in your accessor safe in the knowledge that it will not be a common occurrence.

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如果找不到搜索结果,则返回“ NULL”对象(Return a “NULL” object if search result not found)
    问题 我对C ++相当陌生,因此在学习时,我倾向于使用许多Java风格进行设计。 无论如何,在Java中,如果我有一个带有“搜索”方法的类,该类将从匹配特定参数的Collection< T >返回对象T ,则我将返回该对象,并且如果在集合中未找到该对象,我将返回null 。 然后在我的调用函数中,我只是检查if(tResult != null) { ... } 在C ++中,我发现如果对象不存在,则无法返回null值。 我只想返回类型T的“指示器”,通知调用函数未找到对象。 我不想抛出异常,因为这并不是真正的例外情况。 这是我的代码现在的样子: class Node { Attr& getAttribute(const string& attribute_name) const { //search collection //if found at i return attributes[i]; //if not found return NULL; // what should this be? } private: vector<Attr> attributes; } 我该如何更改它才能提供这种标记? 回答1 在C ++中,引用不能为null。 如果您希望有选择地返回null(如果未找到任何内容),则需要返回一个指针,而不是引用: Attr *getAttribute
  • 当我应该使用 std::map::at 来检索地图元素时(When I should use std::map::at to retrieve map element)
    问题 我已经阅读了网络上的不同文章和 stackoverflow 上的问题,但对我来说,不清楚使用std::map::at来检索地图元素是否更好。 根据定义, std::map::at 返回对使用键 k 标识的元素的映射值的引用。 如果 k 与容器中任何元素的键都不匹配,则该函数会抛出 out_of_range 异常。 对我来说,只有当您 100% 确定具有特定键的元素存在时才值得使用std::map::at情况,否则您应该考虑异常处理。 是否有std::map::at被认为是最有效和最优雅的方式的情况? 在什么情况下你会推荐使用std::map::at ? 当有可能没有具有此类键的元素时,最好使用map::find()是否正确? 而map::find()是更快更优雅的方法吗? if ( map.find("key") != map.end() ) { // found } else { // not found } ps map::operator[]有时可能很危险,因为如果一个元素不存在,那么它会插入它。 编辑:链接以某种方式相关链接 1 链接 2 链接 3 链接 4 链接 5 链接 6 回答1 与此处大多数现有答案相反,请注意,实际上有4种与在地图中查找元素相关的方法(忽略lower_bound 、 upper_bound和equal_range ,它们不太精确):
  • 如何从地图中获取值?(How can I get a value from a map?)
    问题 我有一个名为valueMap的map ,如下所示: typedef std::map<std::string, std::string>MAP; MAP valueMap; ... // Entering data. 然后我通过引用将此映射传递给函数: void function(const MAP &map) { std::string value = map["string"]; // By doing so I am getting an error. } 如何从作为函数引用传递的映射中获取值? 回答1 不幸的是std::map::operator[]是一个非常量成员函数,并且您有一个 const 引用。 您要么需要更改function的签名,要么执行以下操作: MAP::const_iterator pos = map.find("string"); if (pos == map.end()) { //handle the error } else { std::string value = pos->second; ... } operator[]通过向映射添加默认构造值并返回对它的引用来处理错误。 当您只有一个常量引用时,这没有用,因此您需要做一些不同的事情。 您可以忽略这种可能性并写入string value = map.find("string")-
  • 当函数可能没有返回值时,返回类型应该是什么?(What should the return type be when the function might not have a value to return?)
    问题 在过去,您可能有这样的功能: const char* find_response(const char* const id) const; 如果找不到该项目,则可以返回 null 以指示事实,否则显然返回相关字符串。 但是当函数改为: const std::string& find_response(const std::string& id) const; 您返回什么以指示未找到项目? 或者签名真的应该是: bool find_response(const std::string& id, std::string& value) const; 什么是最优雅的现代 C++ 方式? 回答1 提升::可选。 它是专门为这种情况设计的。 请注意,它将作为std::optional包含在即将发布的 C++14 标准中。 更新:在审查了国家机构对 N3690 的评论后, std::optional从 C++14 工作文件中被排除在一个单独的技术规范中。 从 n3797 开始,它不是 C++14 草案的一部分。 与std::unique_ptr相比,它避免了动态内存分配,并且更清楚地表达了它的目的。 然而, std::unique_ptr更适合多态性(例如工厂方法)和在容器中存储值。 用法示例: #include <string> #include <boost/none.hpp>
  • 前端一面基础知识 ②——作用域和闭包(面试场景题)
    前言 根据慕课网的《快速搞定前端技术一面 匹配大厂面试要求》课程所整理的题目,陆续更新 常考面试题 场景题 先直接看一下下面这些基础面试场景题,你都会写吗?场景题的答案请拖动下方滚动条,然后查看注释参考对比自己的答案哦 ①闭包场景题一 function print(fn) { const a = 200 fn() } // 函数作为参数被传递 const a = 100 function fn() { console.log(a) // 在定义的地方往上查找,找到外面全局定义的 a 变量,所以是打印 100 } print(fn) // 100 ②闭包场景题二 function create() { const a = 100 return function () { console.log(a) } } // 函数作为返回值 const fn = create() const a = 200 fn() // 打印 100 ③this、call、bind function fn1() { console.log(this) } fn1() // window fn1.call( { x:100 } ) // call直接就改变指向执行 // {x:100} const fn2 = fn1.bind( { x:200 } ) // 返回一个新的函数执行,所以需要赋值 fn2() //
  • Cloud Firestore:如何在我的集合查询中获取文档引用并将其映射为 JSON 值?(Cloud Firestore: how to fetch a document reference inside my collection query and map it as a JSON value?)
    问题 假设我有一个评论集。 每个评论对象都有一个“doc ref”给发布的用户。 我需要一个查询来返回一个评论列表,包括每个用户引用的值,所以我的查询返回一个很好的格式的 Json 评论对象。 回答1 这里有人问了一个类似的问题,Firestore 参考数据类型有什么用?,我认为根据此答案 https://stackoverflow.com/a/46570119/473453,您不可能按照您的要求进行操作。 您必须自己加载每个引用,例如 const comments = [] firebase.firestore().collection('/comments').get().then(snapshot => { snapshot.docs.forEach(doc => { const comment = doc.data() comment.userRef.get().then(snap => { comment.user = snap.data() comments.push(comment) }) }) }) 对于许多评论,这会增加很多开销。 也许您可以编写一个 CloudFunction,在服务器端为您完成所有工作并返回一个格式化的 JSON。 看起来他们将来可能会支持这个:https://stackoverflow.com/a/46614683/473453 回答2
  • 如何处理对调整大小的哈希表的旧引用?(How to deal with old references to a resized hash table?)
    问题 我目前正在用 C 语言实现哈希表。我正在尝试实现动态调整大小,但遇到了一个问题。 如果调整哈希表的大小意味着创建一个大小为两倍(或一半)的新表、重新散列并删除旧表,我该如何处理用户可能对旧表进行的旧引用? 示例代码(我只是在这个例子中省略了错误检查): int main(int argc, char *argv[]) { ht = ht_create(5) /* make hashtable with size 5 */ ht_insert("john", "employee"); /* key-val pair "john -> employee" */ ht_insert("alice", "employee"); char *position = ht_get(ht, "alice"); /* get alice's position from hashtable ht */ ht_insert("bob", "boss"); /* this insert exceeds the load factor, resizes the hash table */ printf("%s", position); /* returns NULL because the previous hashtable that was resized was freed */ return
  • 《JavaScript高级程序设计(第四版)》红宝书学习笔记(2)(第四章:变量、作用域与内存)
    个人对第四版红宝书的学习笔记。不适合小白阅读。这是part2。持续更新,其他章节笔记看我主页。 (记 * 的表示是ES6新增的知识点,记 ` 表示包含新知识点) 第四章:变量、作用域与内存 4.1 原始值与引用值 ECMAScript变量可以包含两种不同类型的数据:原始值和引用值。原始值(primitive value)就是最简单的数据,引用值(reference value)则是由多个值构成的对象。 在把一个值赋给变量时,JavaScript引擎必须确定这个值是原始值还是引用值。上一章讨论了6种原始值:Undefined、Nu11、Boolean、Number、String和Symbol。保存原始值的变量是按值(byvalue)访问的,因为我们操作的就是存储在变量中的实际值。 引用值是保存在内存中的对象。与其他语言不同,JavaScript不允许直接访问内存位置,因此也就不能直接操作对象所在的内存空间。在操作对象时,实际上操作的是对该对象的引用(reference)而非实际的对象本身。为此,保存引用值的变量是按引用(by reference)访问的。 注意:在很多语言中,字符串是使用对象表示的,因此被认为是引用类型。ECMAScript打破了这个惯例。 4.1.1 动态属性 原始值和引用值的定义方式很类似,都是创建一个变量,然后给它赋一个值。不过,在变量保存了这个值之后
  • 按参数返回值是一个好的设计吗?(Is it a good design to return value by parameter?)
    问题 bool is_something_ok(int param,SomeStruct* p) { bool is_ok = false; // check if is_ok if(is_ok) // set p to some valid value else // set p to NULL return is_ok; } 如果“一切正常”,则此函数返回 true 并将 p 设置为有效值,否则返回 false 并将 p 设置为 NULL 这是一个好还是坏的设计? 就个人而言,我在使用它时感到不舒服。 如果没有文档和评论,我真的不知道如何使用它。 顺便说一句:有没有一些关于 API 设计的权威书籍/文章? 回答1 由于您已将问题标记为 C++ 而不是 C,我建议您: 直接返回值如果您有多个值,请使用输出参数尽可能使用非常量引用作为输出参数(而不是指针),并使用常量引用作为输入参数。 如果出现问题,引发异常而不是返回 false 或 -1。 但这只是一些一般性提示。 最好的方法总是取决于具体的问题...... 回答2 取决于您想如何处理“错误”。 例如,采用标准函数 atoi。 它将字符串转换为整数,但如果字符串不包含数字,它应该返回什么? 在这种情况下,C/C++ 运行时将设置 errno 全局变量。 另一种方法是抛出异常。 就个人而言,我不太喜欢这两种选择。 因此
  • 返回局部于函数的 std::string 的最佳方法(best way to return an std::string that local to a function)
    问题 在 C++ 中,从函数返回函数局部 std::string 变量的最佳方法是什么? std::string MyFunc() { std::string mystring("test"); return mystring; } std::string ret = MyFunc(); // ret has no value because mystring has already gone out of scope...??? 回答1 不,那不是真的。 即使mystring超出范围并被销毁, ret也有 mystring 的副本,因为函数MyFunc按值返回。 回答2 如果你的代码是这样的,就会有问题: std::string& MyFunc() { std::string mystring("test"); return mystring; } 所以,你写的方式没问题。 只是一个建议 - 如果你可以像这样构造字符串,我的意思是 - 你可以在一行中完成,有时这样做会更好: std::string MyFunc() { return "test"; } 或者如果它更“复杂”,例如: std::string MyFunct( const std::string& s1, const std::string& s2, const char* szOtherString ) {
  • 7种你应该知道的JavaScript常见的错误
    从浏览器的控制台到运行Node.js的计算机终端,我们到处都会看到各类错误。 这篇文章的重点是概述我们在JS开发过程中可能遇到的错误类型。 1. RangeError 当数字超出允许的值范围时,将抛出此错误。 例如, 1 2 3 const l = console.log const arr = [90,88] arr.length=90**99 我们有一个带有两个元素的arr。接下来,我们尝试使数组包含90**99 == 2.9512665430652753e+193元素。 这个数字超出了大小数组可以增长的范围。所以运行时它会抛出RangeError: 1 2 3 4 5 $ node errors errors.js:4 arr.length=90**99 ^ RangeError: Invalid array length 因为我们要增加arr数组的数量超出了JS指定的范围。 2. ReferenceError 当对变量/项的引用被破坏或不存在时,将引发此错误。也就是说,变量/项不存在。 例如, 1 2 3 4 5 const l=console.log const cat = "cat" cat dog 我们有一个变量cat初始化为“ cat”。接下来,我们引用cat变量和dog变量。cat变量存在,而dog变量不存在。 cat将返回“ cat”
  • C++补充
    文章目录 C/C++1、在main执行之前和之后执行的代码可能是什么?2、结构体内存对齐问题?3、指针和引用的区别4、堆和栈的区别5、区别以下指针类型?6、基类的虚函数表存放在内存的什么区,虚表指针`vptr`的初始化时间7、`new / delete `与 `malloc / free`的异同8、`new`和`delete`是如何实现的?9、`malloc`和`new`的区别?10、宏定义和函数有何区别?11、宏定义和typedef区别?12、变量声明和定义区别?13、哪几种情况必须用到初始化成员列表?14、`strlen`和`sizeof`区别?15、常量指针和指针常量区别?16、a和&a有什么区别?17、数组名和指针(这里为指向数组首元素的指针)区别?18、野指针和悬空指针19、迭代器失效的情况20、C和C++的区别21.`C++`与`Java`的区别22、C++中`struct`和`class`的区别23、`define`宏定义和`const`的区别24、C++中`const`和`static`的作用25、C++的顶层`const`和底层`const`26、类的对象存储空间?27、final和override关键字28、拷贝初始化和直接初始化29、初始化和赋值的区别30、extern"C"的用法31、模板函数和模板类的特例化32、C和C++的类型安全33
  • 我应该使用什么函数签名来返回对可能不存在的对象的引用?(What function signature should I use to return a reference to an object that might not exist?)
    问题 我正在用 C++ 编写一个简单的容器类,类似于存储由键索引的对象的映射。 我想提供一个访问器功能,例如: V& getValue(const K &key); 我在其中返回对该值的引用。 但我也想处理键/值不存在并能够向用户返回一些状态的情况(可能有一些原因导致我想通过某种状态类型与调用者通信回不存在)。 我想我可以执行以下操作,但调用它需要在调用此函数之前构造一个 V 对象,我只是要将内部 V 对象复制到通过引用传入的对象中,所以这看起来很糟糕. Status getValue(const K &key, V& v); 我也可以这样做: V &getValue(const K &key, Status &s); 但是由于某种原因,这似乎有点笨拙,因为焦点从状态中移开,用户可能会忘记检查它(但也许这不是我的问题)。 那么无论如何有没有类似的功能 Status getValue(const K &key, V& v); 在调用它之前不需要构造一个虚拟的 V 对象吗? 您不能将引用传递给引用。 我想我可以使用指针并且很乐意这样做,但是对于创建一个简单易用和关于函数的推理来说不太理想。 有什么想法吗? 回答1 通常的解决方案是提供一个bool contains(const K &key)函数,如果您不希望访问器静默创建条目,请让它抛出异常。 (有两个访问器,一个抛出异常
  • C++ unordered_map 使用详解(含C++20新特性)
    目录 查找元素 迭代器 容量 修改操作 通接口 哈希策略 观察器 std::swap(std::unordered_map) std::erase_if (std::unordered_map) 简介 本篇博客介绍C++常用的无序关联容器unordered_map。unordered_map是C++11正式加入的对hash_map的官方实现(之前标准C++没有hash_map的官方实现,我们使用的STL的hash_map并不是官方的)。从名字可以看出这个结构是无序的,底层设计思想和STL的hash_map一样。元素在内部不以任何特定顺序排序,而是放进桶中。元素放进哪个桶完全依赖于其键的哈希。这允许对单独元素的快速访问,因为一旦计算哈希,则它准确指代元素所放进的桶。unordered_map搜索、插入和元素移除拥有平均常数时间复杂度。 查找元素 at()用于访问指定元素 T& at( const Key& key ); const T& at( const Key& key ) const; 返回到等于 key 的键的元素的引用。若无该元素,则抛出 std::out_of_range 类型异常。 operator []用于访问或插入元素 T& operator[]( const Key& key ); T& operator[]( Key&& key ); 返回等于 key
  • JavaScript高级程序设计第四版学习--第四章
    title: JavaScript高级程序设计第四版学习–第四章 date: 2021-5-16 20:57:45 author: Xilong88 tags: JavaScript 本章内容 通过变量使用原始值与引用值 理解执行上下文 理解垃圾回收 可能出现的面试题: 1、原始值和引用值的区别 2、参数传值是什么方式? 3、了解过执行上下文吗? 4、了解过作用域链吗? 5、了解过作用域链增强吗? 6、如何判断对象类型?(这里提到有一种) 7、谈谈JavaScript垃圾回收机制 8、了解内存泄漏吗?如何规避? 9、性能优化?(这章里关于:隐藏类,常量池和静态分配) 知识点: 1.两种不同类型的数据:原始值和引用值。原 始值 (primitive value)就是最简单的数据,引用值 (reference value) 则是由多个值构成的对象。 2.保存原始值的变量是按值 (by value)访问的,因为我们操作的就是存储在变量中的实际值。 3.JavaScript不允许直接 访问内存位置,在操作对 象时,实际上操作的是对该对象的引用 (reference)而非实际的对象本 身。为此,保存引用值的变量是按引用 (by reference)访问的。 4.原始值不能有属性,尽管尝试给原始值添加属性不会报错。比如: let name = "Nicholas"; name.age = 27
  • 【C++ | 基础】进阶编程
    C++重点内容 文章目录 进阶编程1. 模板1.1 模板的概念1.2 函数模板1.2.1 普通函数与函数模板的区别1.2.2 普通函数与函数模板的调用规则1.2.3 模板的局限性 1.3 类模板1.3.1 类模板和函数模板区别1.3.2 类模板中成员函数创建时机1.3.3 类模板对象做函数参数1.3.4 类模板与继承1.3.5 类模板成员函数类外实现1.3.6 类模板分文件编写1.3.7 类模板与友元 2. STL初识2.1 STL基本概念2.2 STL中容器、算法、迭代器简介2.2.1 容器2.2.2 算法2.2.3 迭代器 2.3 容器算法迭代器初识2.3.1 vector存放内置数据类型 3. STL常用容器3.1 string容器3.1.1 string构造函数3.1.2 string赋值操作3.1.3 string字符串拼接3.1.4 string查找和替换3.1.5 字符串比较3.1.6 string字符存取3.1.7 string插入和删除3.1.8 string子串 3.2 vector容器3.2.1 vector构造函数3.2.2 vector赋值操作3.2.3 vector容量和大小3.2.4 vector插入和删除3.2.5 vector数据存取3.2.6 vector互换容器3.2.7 预留空间 3.3 deque容器3.3.1 deque基本概念3.3.2
  • C++ 运算符重载中返回值的坑
    C++ 运算符重载中返回值的坑 E0334 "Myclass" 没有适当的复制构造函数E0349 没有与这些操作数匹配的 "<<" 运算符C3861 “function”: 找不到标识符Summary 相信不少朋友在学习运算符重载的时候,都会被参数与返回值应该是左值引用,还是右值引用,还是const常量所困扰。当然我无法一一枚举,这次先讲一下返回值的坑 (没错就是我亲手写的bug) E0334 “Myclass” 没有适当的复制构造函数 其实这个问题的根源是,没有定义常量参数类型的拷贝构造函数所致 先来看看代码 //头文件head.h class Myclass { private: int a; public: Myclass(int b=0):a(b) {} //构造函数 Myclass(Myclass& c); //复制构造函数 ~Myclass(){} //析构函数 Myclass operator+(Myclass& d); //重载+运算符 friend ostream& operator<<(ostream& os ,const Myclass& d); //重载<<运算符 }; //以下是定义 Myclass::Myclass(Myclass& c) { a = c.a; } Myclass Myclass::operator+(Myclass& d) {
  • C++ 返回对临时的引用 [重复](C++ Returning reference to temporary [duplicate])
    问题 这个问题在这里已经有了答案: 10 年前关闭。 可能的重复: 警告:返回对临时的引用 我在下面的第二行收到错误“返回对临时的引用”。 class Object : public std::map <ExString, AnotherObject> const { public: const AnotherObject& Find (const ExString& string ) const { Object::const_iterator it = find (string); if (it == this->end()) { return AnotherObject() }; return ( it->second ); } } 我的班级实现了 std::map。 我是 C++ 的新手,所以我猜它只是一个语法错误。 有什么帮助吗? 回答1 如果您的函数如下所示: AnotherObject& getAnotherObject() { . . . Object::const_iterator it = find ("lang"); if (it == this->end()) { return AnotherObject() }; . . . } 问题是您返回的 AnotherObject() 将在函数退出后立即销毁,因此您的函数的调用者将引用一个虚假对象。 但是
  • JavaScript高级程序设计第四版学习记录-第四章 变量、作用域与内存
    文章目录 4.1 原始值与引用值4.1.1 动态属性4.1.2 复制值4.1.3 传递参数4.1.4 确定类型 4.2 执行上下文与作用域4.2.1 作用域链增强4.2.2 变量声明1、使用`var` 的函数作用域声明2、使用 let 的块级作用域声明3、使用 `const` 的常量声明4、标识符查找 4.3 垃圾回收4.3.1 标记清理4.3.2 引用计数4.3.3 性能4.3.4 内存管理1. 通过const 和 let 声明提升性能2. 隐藏类和删除操作3. 内存泄漏4. 静态分配与对象池 4.4 小结4.4.1 变量4.4.2 作用域4.4.3 内存 JavaScript 变量是松散类型的,而且变量不过就是特定时间点一个特定值的名称而已。由于没有规则定义变量必须包含什么数据类型,变量的值和数据类型在脚本生命期内可以改变。 4.1 原始值与引用值 ECMAScript 变量包含两种不同类型的数据:原始值和引用值。原始值(primitive value)是最简单的数据,引用值(reference value)是由多个值构成的对象。 在把一个值赋给变量时,JavaScript 引擎必须确定这个值是原始值还是引用值。这两种类型的存储方式不同: 原始值(6种):Undefined、Null、Boolean、Number、String 、 Symbol。保存原始值的变量是按值(by
  • C++ 沧海拾遗
    Tricks emplace_back优于push_backsome_str.find(“abccde”) != std::string::npositer = some_set.erase(iter);实践中提高vector性能的要点是尽量使用reserve(仅次于换编译器和STL实现)。运行期依然不能确定数组的个数,明智的选择是什么也不做,push_back/emplace_back就足够;运行期能确定个数,则应该用reserve,不建议用传递大小的数组构造函数或者调用resize。vector,map这些直接用下标不会导致越界,要是使用带越界的版本,就用at成员函数。熟悉常见常见的算法:https://zh.cppreference.com/w/cpp/header/algorithm关于左值右值。左值是可以找到地址的变量(可以&),右值自然就找不到了。一般来说,表达式的临时结果,没有可识别的内存位置(也就是说,只存在于计算过程中的每个临时寄存器中),因此都是右值。最开始的时候,左值在 C 中定义为“可以出现在赋值操作左边的值”。然而,当 ISO C 加入 const 关键字后,这个定义便不再成立。通常来说,表达式的计算的参数输入接受的是右值,返回的也是右值。关于引用。我们可以对左值进行引用,因为得到了他的地址就可以对其进行赋值。也是因为这个原因,我们不能对右值进行引用