Ekos IV
Ekos IV

Reputation: 367

Function const return type: invalid initialisation of reference of type

I have this function:

Triangle& Triangle::get_largest_triangle(const Triangle& t) const
{
    float area_this = get_area();
    float area_other = t.get_area();

    if (area_other > area_this)
        return *this;
    else
        return t;
}

This doesn't work unless I declare the returned Triangle to be constant, i.e.:

const Triangle& Triangle::get_largest_triangle(const Triangle& t) const

Why is this? I'm fairly new to C++ but as far as I can tell, neither 'this', nor the object in the parameter list are being changed in the function so I don't really see what the issue is.

e.g. What if I want to change some of the values stored in the largest Triangle after running this function?

Upvotes: 0

Views: 76

Answers (6)

Murphy
Murphy

Reputation: 3999

Passing a const reference to the method the compiler guarantees that the object won't be changed. You try to return a non-const reference of the same object, which would lead to t loosing its constness, and the compiler is preventing you from doing that.

Rethink if you're doing the right thing here. Why can't you either use a non-const reference for t, or return a const reference?

Upvotes: 0

Alan Stokes
Alan Stokes

Reputation: 18964

You're trying to convert t, a reference to a const Triangle, to a reference to a modifiable Triangle. That would allow the caller to modify t, which would be a bad thing.

You need to change your return type to make it const.

Upvotes: 1

Christophe
Christophe

Reputation: 73376

You have defined your function being const, i.e. not changing the state of the object:

Triangle& Triangle::get_largest_triangle(const Triangle& t) const

The problem is that you return a non const reference:

  • if your return *this, the non const reference could be used to change the object's state.
  • if you return t, the non const reference could be used to modify an object which you said taht you wouldn't change.

This is why the compiler complains. Just say that you return a reference to a const to solve your issue:

const Triangle& Triangle::get_largest_triangle(const Triangle& t) const

Upvotes: 1

robal
robal

Reputation: 368

Consider following use of your function

const Triangle t1, t2;
Triangle &t3 = t1.get_largest_triangle(t2);

t3 is now modifiable but this is reference to either t1 or t2. So your code can 'accidentally' drop constness of objects. If this was possible c++ type system wouldn't be safe.

Theoretically because t1 and t2 are const they could be allocated in non modyfiable memory and when you will try to change one of them via t3 which you are allowed to do, program can crash.

Upvotes: 1

AaronI
AaronI

Reputation: 862

This function returns a non-const reference to a Triangle. This means that the caller can modify the returned object. But it returns either a reference to itself (which is const due to the function declaration), or a reference to the function argument (which is also const). So the compiler won't allow it because you are making a const object non-const.

Your options are to change the function signature to return a const:

const Triangle& Triangle::get_largest_triangle(const Triangle& t) const

or alternatively to make the method non-const and take a non-const reference:

Triangle& Triangle::get_largest_triangle(Triangle& t)

Upvotes: 2

David Haim
David Haim

Reputation: 26496

When you return t, you return const Triangle& , which is the type of t.
when you declare your function to return Triangle& you are returning different type. remember, const is part of the type.
Triangle& is not const Triangle&.

Just change the return type of get_largest_triangle to be const Triangle&, or change the type of t to be Triangle&. both have their cons and pros.

Upvotes: 1

Related Questions