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

rav*_*avi 3 c++ temporary-objects

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

情况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;
}
Run Code Online (Sandbox Code Playgroud)

这会给我错误,因为我试图用非常量引用参数临时绑定。

案例2:-

try
{
 throw e;
}
catch ( exception& e )
{
}
Run Code Online (Sandbox Code Playgroud)

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

catch 正在做的是通过非常量引用来捕获这个异常。这与我在案例 1 中展示的相反。

所以,我的问题是:-

1) 是否有允许临时绑定到非常量引用的特定场景。

2)如果有那么在允许这些例外时考虑了哪些因素。

0x4*_*2D2 5

是否有允许临时绑定到非常量引用的特定场景。

对于左值引用(即类型T&),没有。您不能将临时对象绑定到非常量左值引用,因为修改例如像42. 它们可以绑定到const lvalue-references,因为这样已经做出了修改引用绑定到的对象的承诺。

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

如果有,那么在允许这些例外时考虑了哪些因素。

确实,临时对象不能绑定到非常量左值引用,但对异常对象有一定的规定:

取自 C++11 标准(最近的草案n3337):

§15.1/3 throw 表达式初始化一个临时对象,称为 异常对象,其类型是通过从 throw 的操作数的静态类型中删除任何顶级 cv 限定符并从“数组T”或“函数返回 T”分别为“指向 T 的指针”或“指向返回 T 的函数的指针”。临时变量是一个左值,用于初始化匹配处理程序(15.3) 中命名的变量[..]

强调我的

cppreference 将其简化为:

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

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