views:

86

answers:

1

I was reading this question here here regarding const-correctness. The Scott Meyer solution seems like a good work-around, but what if you have a member function (which requires both a const and non-const version) that makes use of the this pointer. If the member function is const then this automatically means const this, which can make it difficult to have a single const function where the bulk of the code lies.

One possible work-around that occurred to me was simply to pass a reference to this to the const function as a parameter, so the function can use that reference instead of directly using the this pointer. But, is this safe? It seems to be safe (if very hacky), because you're not actually using const_cast on a const-object. Rather, you're simply circumventing the contract provided by the const member function by passing it a non-const reference of the object.

For example:

class Foo
{
    private:

    template <class SelfReference>    
    void f1(SelfReference& self) const
    { 
        // We now might have a non-const reference to "this", even though
        // we're in a const member function.  But is this safe???
    }

    public:    

    void f2()
    {
        f1(*this);
    }

    void f2() const
    {
        f1(*this);
    }
};

This seems to provide a nice way to avoid having to duplicate large quantities of code when a const and non-const version of a function is required, but is this safe? Or does it cause undefined behavior somehow?

A: 

Note that even if you are in const f1() function and you can modify "this", f2() is marked as non-const, thus by calling f2() object may be modified. And f1() alone will not let you to modify "this" within itself (or any const object). You even can't call f2() in aid of const Foo object, so this doesn't bring any benefit.

In other words - in your example non-const f1() would be sufficient. You don't need f1() const or both versions here.


UPDATE Now you won't be able to modify self in "const" version of f1() that is void f1(const Foo & self) const called from void f2() const.

doc
I modified it a bit: the idea is that you have two versions of f2 (const and non-const), both of which call f1 which is `const`. However, the non-const version of f2 passes a non-const self-reference, whereas the const version of f2 passes a const self-reference. So the idea is that most of the logic can go in f1 to avoid duplication.
Channel72
@doc, I understand that - but the idea is not actually to modify `this` from a constant member function, but just to avoid code duplication. So if for any reason f1 has to use the `this` pointer, say to pass it to an iterator or something, then there is no need to write a separate const version of f1.
Channel72
@Channel72: If you won't modify object, then `const` version of method is perfectly sufficient. You can call `const` function from non-const one. You don't ever need non-const version of function in such case, so the code won't be duplicated.
doc