【问题标题】:Temporary object and non-const reference临时对象和非常量引用
【发布时间】:2014-02-05 14:41:38
【问题描述】:

我不明白为什么我在使用以下代码时不断收到编译错误。

一个简单的结构及其初始化辅助函数:

typedef struct _ccColor4F 
{
    GLfloat r;
    GLfloat g;
    GLfloat b;
    GLfloat a; 
} ccColor4F;

static inline ccColor4F  ccc4f(const GLfloat r, const GLfloat g, const GLfloat b, const GLfloat a)  
{
    ccColor4F c4 = {r, g, b, a};
    return c4; 
}

以及使用该结构的方法:

void TexturePolygon::setColor(ccColor4F &color);

现在,如果我尝试使用下面的 init 函数,我会收到编译错误。

poly->setColor(ccc4f(1.f, 1.f, 1.f, 1.f));

对“ccColor4F”类型(又名“cocos2d::_ccColor4F”)的非 const 左值引用不能绑定到“ccColor4F”类型的临时对象

我必须将 setColor 的参数更改为“常量引用”以避免错误。我知道临时对象必须绑定到 const 引用。但在这种情况下,它是一个内联函数,所以不应该有任何临时对象。我错过了什么吗?

谢谢。洛朗

【问题讨论】:

  • 我不知道你为什么认为inline 在这里会有所作为。
  • inline 允许您在多个翻译单元中定义函数(对于许多编译器来说,内联调用它是必需的)。它不会强制内联调用,也不会更改其任何语义。引用参数仍被视为引用,即使它已被优化。
  • @FredLarson 我以为inline 会改变调用的语义。

标签: c++ c++11


【解决方案1】:

inline 的功能与天气无关,或者对象不是临时的。

inline 不会做你认为的那样。它甚至没有像许多人认为的那样做。

inline 所做的是使函数可以在多个翻译单元中定义。 inline 所做的是使代码内联扩展(这是一个提示,而不是要求。编译器可以并且会忽略你。),它对语义没有任何影响调用、参数或返回。

在您的代码中:

poly->setColor(ccc4f(1.f, 1.f, 1.f, 1.f));

ccc4f(1.f, 1.f, 1.f, 1.f)构造的对象临时的。 setColor()inline 的事实没有区别。

如果你需要向setColor()发送一个非临时的,那么你必须构造一个非临时的ccc4f

ccc4f myObj(1.f, 1.f, 1.f, 1.f);
poly->setColor (myObj);

您可以设置此范围,以便在您调用 setColor 后立即销毁 myObj

{
  ccc4f myObj(1.f, 1.f, 1.f, 1.f);
  poly->setColor (myObj);
}

但这似乎毫无意义,因为myObj 似乎不是 RAII 对象。为什么不让setColor 接受const 引用并完成它?

【讨论】:

  • 好的。我现在明白了。我错误地认为内联可能会改变调用的语义。 PS:我将更改为 const 参考。只是我不明白为什么我必须在这种情况下。谢谢!
【解决方案2】:

您的 setColor 函数期望获得可分配的内存引用,这意味着它应该能够做到

color = NULL;

如果它愿意的话。您的代码不允许这样做,因为您提供的是一个临时对象。

这里的推理是什么? setColor 函数改变了color 参数,在这种情况下,给它一个临时对象是没有意义的;或者setColor 函数不会更改color 参数,在这种情况下,它应该作为常量引用传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 2019-02-05
    • 2011-05-31
    • 1970-01-01
    • 2012-11-29
    相关资源
    最近更新 更多