gpt4 book ai didi

c++ - 返回非常量左值引用

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:27:22 24 4
gpt4 key购买 nike

我正在尝试使用Interactive computer graphics - A top-down approach这本书来学习计算机图形学,示例代码是in this link

有一个名为“mat.h”的头库提供了一些矩阵实用程序,但是当我尝试使用 Xcode 进行编译时,会抛出以下错误:

对类型“Angel::mat2”的非常量左值引用不能绑定(bind)到类型“Angel::mat2”的临时值

抛出该错误的代码是:

mat2& operator /= ( const GLfloat s ) {
#ifdef DEBUG
if ( std::fabs(s) < DivideByZeroTolerance ) {
std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] "
<< "Division by zero" << std::endl;
return mat2();
}
#endif // DEBUG

我只是将其注释掉,因为它只是在调试应用程序时被编译,但我想知道问题出在哪里以及如何解决。

最佳答案

严格来说,虽然错误的正式原因是试图将一个非常量引用绑定(bind)到一个临时对象,但这里真正的问题是试图返回一个引用对临时对象的任何引用。引用是否为 const 无关紧要。

临时对象将在 return 语句完成后立即销毁,从而导致返回绑定(bind)到现已销毁对象的悬空引用。换句话说,即使我们试图通过将返回类型更改为 const 引用来“修复”这段代码,它仍然无法正常工作。

此外,根据设计,此函数似乎应该返回非常量引用,这意味着更改此函数的返回类型不是一个选项。非常量引用是复合赋值运算符通常返回的内容。在“除以零”的情况下,调试分支应该提前终止(当然,返回一些东西,任何只是为了使代码编译)。

实现这一点的一种方法是声明一个类型为 mat2 的独立对象(例如,作为类 mat2 的静态成员)并返回对它的引用。 IE。声明

class mat2 {
...
#ifdef DEBUG
static mat2 bad_result;
#endif // DEBUG
};

定义它

#ifdef DEBUG
mat2 mat2::bad_result;
#endif // DEBUG

然后做

return bad_result;

每当检测到错误时。

或者(更容易)您可以在 return 语句之前在本地声明它

#ifdef DEBUG
if ( std::fabs(s) < DivideByZeroTolerance ) {
std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] "
<< "Division by zero" << std::endl;
static mat2 bad_result;
return bad_result;
}
#endif // DEBUG

当然,这种设计有一个明显的缺陷,因为外部代码将能够修改返回的对象,这是不可取的。然而,最有可能的想法是,一旦将错误消息打印到 std::err,就无法保证程序的行为,这意味着在这种情况下,返回值的可修改性应该不是问题。

考虑到最后一点,我们甚至可以使用非静态局部变量作为返回值

#ifdef DEBUG
if ( std::fabs(s) < DivideByZeroTolerance ) {
std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] "
<< "Division by zero" << std::endl;
mat2 bad_result;
return bad_result;
}
#endif // DEBUG

返回对局部变量的引用与返回对临时变量的引用一样错误(原因大致相同)。但是,在“错误后无保证”方法中,它将“起作用”,这意味着它将修复错误消息。

关于c++ - 返回非常量左值引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14512343/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com