Laurent Zubiaur
Laurent Zubiaur

Reputation: 438

Temporary object and non-const reference

I can't figure out why I keep getting a compilation error when using the following code.

A simple structure and its init helper function:

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

and a method using the structure:

void TexturePolygon::setColor(ccColor4F &color);

Now if I try to use the init function as follow I get a compilation error.

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

non-const lvalue reference to type 'ccColor4F' (aka 'cocos2d::_ccColor4F') cannot bind to a temporary of type 'ccColor4F'

I have to change the parameter of setColor to a "const reference" to avoid the error. I understand that a temporary object must be bound to a const reference. But in this case it's an inline function so there shouldn't be any temporary object. Am I missing something?

Thanks. Laurent

Upvotes: 0

Views: 170

Answers (2)

John Dibling
John Dibling

Reputation: 101446

The function being inline has no bearing on weather or not the object is a temporary.

inline doesn't do what you think it does. It doesn't even do what many people think it does.

What inline does is make it so that a function can be defined in multiple translation units. What inline doesn't do is make the code expand inline (it's a hint, not a requirement. The compiler can and will ignore you.), not does it have any effect on the semantics of the call, the parameters or the returns.

In your code:

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

The object constructed by ccc4f(1.f, 1.f, 1.f, 1.f) is a temporary. The fact that setColor() is inline makes no difference.

If you need to send a non-temporary to setColor(), then you have to construct a non-temporary ccc4f:

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

You could scope this so that myObj is destroyed right after you call setColor:

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

But that seems rather pointless as myObj doesn't appear to be an RAII object. Why not just have setColor accept a const reference and be done with it?

Upvotes: 3

PaF
PaF

Reputation: 3477

Your setColor function expects to get an assignable memory reference, meaning it should be able to do

color = NULL;

if it so desires. Your code doesn't allow for that, because you're giving a temporary object.

What's the reasoning here? Either the setColor function changes the color parameter, in which case it doesn't make sense giving it a temporary object; or the setColor function doesn't change the color parameter, in which case it should be passed as a const-reference.

Upvotes: 2

Related Questions