将函数 return 值传递给引用参数导致 GCC 中的编译错误
Pass function return value to reference parameter cause compilation error in GCC
假设我声明了这个函数:
class A
{
...
public:
void setRect(Rect & rct);
...
}
成员setRect
是这样称呼的
A a;
a.setRect(Some_Func_Return_A_Rect_Object());
gcc 编译器抱怨找不到匹配的函数A::setRect(Rect)
如果我这样调用就可以了:
A a;
Rect rct = Some_Func_Return_A_Rect_Object();
a.setRect(rct);
标准对此有说明吗? GCC 只是不允许调用 setRect()
函数的第一种方式?
GCC 正确。
如果按值 Some_Func_Return_A_Rect_Object()
returns,即 Rect Some_Func_Return_A_Rect_Object()
,那么对于 a.setRect(Some_Func_Return_A_Rect_Object());
,Some_Func_Return_A_Rect_Object()
returns 是临时的,它不能't be bound to non-const lvalue reference (i.e. Rect &
).
rct
是命名变量,可能绑定到非常量左值引用,因此 a.setRect(rct);
有效。或者,如果可能,您可以将参数类型更改为 const 引用(即 const Rect &
),它可以与 temporary.
绑定
我假设 a.setRect(Some_Func_Return_A_Rect_Object());
函数是 return 值对象。存储在堆栈中的值类型对象和 Some_Func_Return_A_Rect_Object()
的堆栈在函数 return 后展开。
但是您可以将 return 值(临时对象)提取到 const 左值引用,右值引用。
你应该把void setRect(Rect & rct);
的功能当作void setRect(const Rect & rct);
。那么你的编译问题就解决了。
要么
在 C++11 之后,您还可以将 void setRect(Rect & rct);
作为右值引用 void setRect(Rect && rct);
。
假设我声明了这个函数:
class A
{
...
public:
void setRect(Rect & rct);
...
}
成员setRect
是这样称呼的
A a;
a.setRect(Some_Func_Return_A_Rect_Object());
gcc 编译器抱怨找不到匹配的函数A::setRect(Rect)
如果我这样调用就可以了:
A a;
Rect rct = Some_Func_Return_A_Rect_Object();
a.setRect(rct);
标准对此有说明吗? GCC 只是不允许调用 setRect()
函数的第一种方式?
GCC 正确。
如果按值 Some_Func_Return_A_Rect_Object()
returns,即 Rect Some_Func_Return_A_Rect_Object()
,那么对于 a.setRect(Some_Func_Return_A_Rect_Object());
,Some_Func_Return_A_Rect_Object()
returns 是临时的,它不能't be bound to non-const lvalue reference (i.e. Rect &
).
rct
是命名变量,可能绑定到非常量左值引用,因此 a.setRect(rct);
有效。或者,如果可能,您可以将参数类型更改为 const 引用(即 const Rect &
),它可以与 temporary.
我假设 a.setRect(Some_Func_Return_A_Rect_Object());
函数是 return 值对象。存储在堆栈中的值类型对象和 Some_Func_Return_A_Rect_Object()
的堆栈在函数 return 后展开。
但是您可以将 return 值(临时对象)提取到 const 左值引用,右值引用。
你应该把void setRect(Rect & rct);
的功能当作void setRect(const Rect & rct);
。那么你的编译问题就解决了。
要么
在 C++11 之后,您还可以将 void setRect(Rect & rct);
作为右值引用 void setRect(Rect && rct);
。