Cannot convert 'this' pointer from 'const Line' to 'Line &' explanation?

Casey picture Casey · Jul 8, 2011 · Viewed 58.5k times · Source

This method:

bool Point::Intersects(const Line& line) const {
    return (line.ContainsPoint(*this, false));
}

causes this error: cannot convert 'this' pointer from 'const Line' to 'Line &' This change:

bool Point::Intersects(const Line& line) const {
    return const_cast<Line&>(line).ContainsPoint(*this, false);
}

fixes the error, but doesn't seem the right way to fix the issue. Why is the original method considered an error?

If it helps, ContainsPoint(const Point& point, bool isInfinite) is non-const and all methods it calls are non-const as well.

Answer

Ken Wayne VanderLinde picture Ken Wayne VanderLinde · Jul 8, 2011

You actually provided the answer yourself, in a sense.

In your Intersects method, the parameter line is declared const. This restricts how you can use this variable. Specifically, you can only call const methods on it, and you can only pass it to methods expecting a const Line object.

However, you pointed out that ContainsPoint is not declared const. So it does not satisfy the requirement mention above (i.e. calling a non-const method on a const object is not allowed). This is why the original method generates the error, and it also explains why your second version works, since the restriction is alleviated via the const_cast.

The real problem is in the declaration of ContainsPoint (and probably also with whatever methods it calls, as they are also non-const). There appears to be a large design flaw here. Since the purpose of ContainsPoint is to check whether or not a Point is on a Line, side-effects will be unexpected. So there should be no reason for it to not be a const method. In fact (and your example shows this), users of Line would expect ContainsPoint to be a const method. Therefore, the real solution is to change the design of the Line class so that methods like ContainsPoint are declared const, and only methods which clearly change the state of an instance are left non-const