0
votes

I have the following code:

class MyClass;
typedef void(MyClass::*func_ptr)();
class MyClass
{
public:

MyClass()
{
    f = &MyFunc1;
}

void MyFunc1()
{
    // ...
}

void MyFunc2() const
{
    (this->*f)();
}

func_ptr f;

};

If I try to compile, it fails because of MyFunc2() which is a const method trying to call the function pointer of type func_ptr which is non-const.

I'm trying to figure out the best way to cast this. I can use a standard C style cast:

    typedef void(MyClass::*func_ptr2)() const;
    func_ptr2 f2 = (func_ptr2)f;
    (this->*f2)();

But I'd prefer to use a C++ cast (i.e. static_cast, reinterpret_cast, or const_cast). I got this to compile with reinterpret_cast but I can't get it working with const_cast. I thought const_cast was mean't to be used for this case? Also, is there a cleaner way to do this without having to create another typedef?

3
How can there be a clean way to call a non-const function from a const one. There probably is a reason why one of the functions is const and the other is not. If not so, just modify the const qualifiers. - Frank Puffer
The comment above (by @FrankPuffer) should be credited as the correct answer to this question IMO. If those functions are indeed different in their "const-ness", then don't call the non-const function from within the const function. If they're not different, then just change the (incorrect) declaration. - barak manos

3 Answers

2
votes

The typical solution would be (const_cast<MyClass*>(this)->*f)();.

This is legal as long as the MyClass instance has been created non-const. Else, this would invoke undefined behavior.

1
votes

There are a couple of issues in this code.

 f = &MyFunc1;

Is not well-formed C++ because taking an address of a non-static member function requires a fully qualified name:

 f = &MyClass::MyFunc1;

this is MyClass const* in a const member function. You may need to cast away that const:

(const_cast<MyClass*>(this)->*f)();

A better solution may be to rethink the design to avoid fighting the type system with const_cast.

0
votes

The following seems to compile:

MyClass()
{
    f = &MyClass::MyFunc1;
}

void MyFunc1()
{
    // ...
}

void MyFunc2() const
{
    MyClass* mc = const_cast<MyClass*>(this);
    (mc->*f)();
}