如何从成员函数指针中删除const限定符

时间:2014-04-22 07:40:09

标签: c++ templates pointers c++11 function-pointers

我正在使用包含以下代码的库:

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;
    };
    //...

但是,此代码不接受const成员函数指针。传递它们会产生错误Function cannot return function type 'void () const'或const成员函数的任何类型。

如何从传递的成员函数中删除const限定符,或者如何应用std::remove_const

2 个答案:

答案 0 :(得分:1)

作为评论中提到的Adam S,当他尝试编译使用库this simple codeSelene时会发生此错误:

#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);
}

编译器无法编译Class.h标头中的代码。其中包含类_register_member的函数成员Class的两个重载:

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...)) {
        // ...
    }

    // ...

};

当指向const函数成员的指针作为第三个参数传递时,编译器不能选择第二个重载。应该有另一个可以接受const函数成员的重载。它应声明如下:

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

如果没有这样的重载,编译器会选择创建的第一个重载来处理指向数据成员(不是函数成员)的指针,并且无法编译其代码。

因此,在使用当前版本的 Selena 库时,您无法与const个函数成员打交道(至少以这样的方式)。

答案 1 :(得分:1)

我应该提一下,对于那些现在看到这个的人,这实际上是我的代码中的一个错误(真的是一个疏忽),并且在问题被识别后不久就修复了。