简体   繁体   English

在异常情况下将临时绑定到非常量引用

[英]Binding temporaries to non-const references in case of exceptions

I have always read that temporaries are allowed to bind only with non-const reference arguments in case of function calls.. 我一直读到,在函数调用的情况下,允许临时对象仅与非常量引用参数绑定。

CASE 1:- 情况1:-

For example:- 例如:-

class Simple{
    public: 
       int i;
       Simple(Simple &f)
       {
         i = f.i + 1;
       }
       Simple(int j)
       {
         i = j;
       }
  };

int main()
{
   Simple f1 = Simple(2);   // error no matching call fruit::fruit(fruit)...
   return 0;
}

This would give me error as I am trying to bind temporary with non-const reference arguments. 这将给我错误,因为我试图将临时对象与非常量引用参数绑定在一起。

CASE 2:- 案例2:-

try
{
 throw e;
}
catch ( exception& e )
{
}

I have learnt when we throw an exception what really get passed to catch is the copy of original exception thrown ie a temporary is created for the object thrown and then this would be passed to catch clause. 我了解到,当我们抛出异常时,真正传递给catch的是原始抛出的异常的副本,即为抛出的对象创建了一个临时对象,然后将其传递给catch子句。

What catch is doing is catching this exception by non-const reference. catch所做的是通过非const引用捕获此异常。 This is in contrast to what I have shown in CASE 1. 这与我在案例1中展示的相反。

So, my questions are:- 所以,我的问题是:

1) Are there specific scenarios where binding temporary to non-const reference is allowed. 1)是否存在允许临时绑定到非const引用的特定方案。

2) If there are then what factors are taken into account while allowing these exceptions. 2)如果有,那么在允许这些例外时要考虑哪些因素。

Are there specific scenarios where binding temporary to non-const reference is allowed. 是否存在允许临时绑定到非const引用的特定方案。

For lvalue-references (that is, the type T& ) there isn't. 对于左值引用(即类型T& ),没有。 You can't bind a temporary to a non-const lvalue-reference because it doesn't make much sense to modify, say, a literal like 42 . 您不能将临时绑定到非常量左值引用,因为修改像42这样的文字没有太大意义。 They can bind to const lvalue-references because then a promise has been made not to modify the object to which the reference is bound. 它们可以绑定到const lvalue-references,因为这样可以保证不会修改引用所绑定的对象。

They can in fact bind to rvalue -references ( T&& ), but that's unrelated to this thread. 实际上,它们可以绑定到rvalue -referencesT&& ),但这与该线程无关。

If there are then what factors are taken into account while allowing these exceptions. 如果存在,那么在允许这些例外时要考虑哪些因素。

It is true that temporaries cannot bind to non-const lvalue-references, but there's a certain provision made for exception objects: 确实,临时对象不能绑定到非常量左值引用,但是对异常对象有一定的规定:

Taken from the C++11 standard (closest draft n3337 ): 取自C ++ 11标准(最新草案n3337 ):

§15.1/3 A throw-expression initializes a temporary object, called the exception object , the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw and adjusting the type from “array of T” or “function returning T” to “pointer to T” or “pointer to function returning T”, respectively. §15.1/ 3 throw-expression会初始化一个临时对象,称为异常对象 ,其类型是通过从throw操作数的静态类型中删除所有顶级cv限定符并从“ array of array”中调整类型来确定的。 T”或“函数返回T”分别为“ T的指针”或“函数返回T的指针”。 The temporary is an lvalue and is used to initialize the variable named in the matching handler (15.3). 临时变量是一个左值,用于初始化在匹配处理程序 (15.3)中命名的变量 [..] [..]

emphasis mine 重点矿

cppreference simplifies this into: cppreference将其简化为:

Unlike other temporary objects, the exception object is considered to be an lvalue argument when initializing the catch clause parameters, so it can be caught by lvalue reference, modified, and rethrown. 与其他临时对象不同,在初始化catch子句参数时,异常对象被视为左值参数,因此可以通过左值引用对其进行捕获,修改和重新抛出。

So for this case you can in fact bind the exception to a non-const lvalue-reference. 因此,对于这种情况,您实际上可以将异常绑定到非常量左值引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM