在发生异常的情况下将临时绑定到非const引用

在发生异常的情况下将临时绑定到非const引用

问题描述:

我一直读到,在函数调用的情况下,临时对象只能与非常量引用参数绑定..

I have always read that temporaries are allowed to bind only with non-const reference arguments in case of function calls..

情况1:-

例如:-

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;
}

当我尝试将临时对象与非const参考参数绑定时,这将给我带来错误.

This would give me error as I am trying to bind temporary with non-const reference arguments.

情况2:-

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

我了解到,当我们抛出异常时,真正传递给catch的是原始抛出的异常的副本,即为抛出的对象创建一个临时对象,然后将其传递给catch子句.

I have learnt when we throw an exception what really get passed to catch is the copy of original exception thrown i.e a temporary is created for the object thrown and then this would be passed to catch clause.

catch所执行的操作是通过非const引用捕获此异常.这与我在案例1中展示的相反.

What catch is doing is catching this exception by non-const reference. This is in contrast to what I have shown in CASE 1.

所以,我的问题是:-

1)是否存在允许临时绑定到非const引用的特定方案.

1) Are there specific scenarios where binding temporary to non-const reference is allowed.

2)如果允许的话,那么在考虑哪些因素的同时.

2) If there are then what factors are taken into account while allowing these exceptions.

在某些特定情况下,允许将临时绑定到非const引用.

Are there specific scenarios where binding temporary to non-const reference is allowed.

对于左值引用(即类型T&)没有.您不能将临时绑定到非常量左值引用,因为修改42这样的文字没有太大意义.它们可以绑定到 const 左值引用,因为这样就答应了 not 来修改引用所绑定的对象.

For lvalue-references (that is, the type T&) there isn'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. 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.

它们实际上可以绑定到 rvalue -references (T&&),但这与该线程无关.

They can in fact bind to rvalue-references (T&&), but that's unrelated to this thread.

如果允许这些例外,那么要考虑哪些因素.

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:

来自C ++ 11标准(最新草案

Taken from the C++11 standard (closest draft n3337):

§15.1/3 throw-expression 初始化一个临时对象,称为 异常对象,其类型是通过从throw操作数的静态类型中删除所有顶级cv限定词来确定的 并将类型从"T的数组"或返回T的函数"调整为 指向T的指针"或返回T的函数的指针". 临时变量是一个左值,用于初始化在中命名的变量 匹配的 handler (15.3). [..]

§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. The temporary is an lvalue and is used to initialize the variable named in the matching handler (15.3). [..]

强调地雷

cppreference 将其简化为:

与其他临时对象不同,在初始化catch子句参数时,异常对象被视为左值参数,因此可以通过左值引用对其进行捕获,修改和重新抛出.

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.

因此,在这种情况下,您实际上可以将异常绑定到非常量左值引用.

So for this case you can in fact bind the exception to a non-const lvalue-reference.