Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove const qualifier from a member function pointer

I'm using a library which contains the following code:

template <typename M>
void _register_member(lua_State *state,
                      const char *member_name,
                      M T::*member) {
    std::function<M(T*)> lambda_get = [member](T *t) {
                //^ error here
        return t->*member;
    };
    //...

However this code does not accept const member function pointers. Passing those yields the error Function cannot return function type 'void () const' or whatever the type of the const member function is.

How do I remove the const qualifier from the passed member function or how do I apply std::remove_const?

like image 989
Appleshell Avatar asked Apr 22 '14 07:04

Appleshell


People also ask

How to remove const from a pointer c++?

The statement int* c = const_cast<int>(b) returns a pointer c that refers to a without the const qualification of a . This process of using const_cast to remove the const qualification of an object is called casting away constness. Consequently the compiler does allow the function call f(c) .

Do not cast away a const qualification?

Do not cast away a const qualification on an object of pointer type. Casting away the const qualification allows a program to modify the object referred to by the pointer, which may result in undefined behavior.

What does the const member function qualifier?

The const qualifier at the end of a member function declaration indicates that the function can be called on objects which are themselves const. const member functions promise not to change the state of any non-mutable data members.

Can you cast away const in C?

Yes, if a variable is declared const, casting away const-ness from a pointer to it and then writing to it is undefined.


1 Answers

As Adam S noted in comments this error occurs when he tries to compile this simple code which uses the library Selene:

#include <selene.h>

class C {
public:
    bool get() const;
};

bool C::get() const {return true;}

int main() {
    sel::State state;
    state["C"].SetClass<C>("get", &C::get);
}

The compiler fails to compile the code in Class.h header. There are two overloads of function member _register_member of the class Class in it:

template <typename T,
          typename A,
          typename... Members>
class Class : public BaseClass {
private:

    // ...

    template <typename M>
    void _register_member(lua_State *state,
                          const char *member_name,
                          M T::*member) {
        // ...
    }

    template <typename Ret, typename... Args>
    void _register_member(lua_State *state,
                          const char *fun_name,
                          Ret(T::*fun)(Args...)) {
        // ...
    }

    // ...

};

The compiler can't choose the second overload when a pointer to a const function member is passed as a third argument. There should be another overload which could accept a const function member. It should be declared as follows:

template <typename Ret, typename... Args>
void _register_member(lua_State *state,
                      const char *fun_name,
                      Ret(T::*fun)(Args...) const)
                                            ^^^^^

Without such overload the compiler chooses the first overload which is created to work with pointers to data members (not function members) and fails to compile its code.

So you can't deal with const function members when using current version of Selena library (in such way as you do it at least).

like image 83
Constructor Avatar answered Sep 20 '22 18:09

Constructor