【问题标题】:How to remove const qualifier from a member function pointer如何从成员函数指针中删除 const 限定符
【发布时间】:2014-06-06 11:09:53
【问题描述】:

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

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

【问题讨论】:

  • 您的代码有很多问题。为什么将M(T*) 作为模板参数传递给std::function(由于程序的逻辑应该是简单的M)?据我所知,表达式 t-&gt;*member 不能在没有参数列表的情况下使用。它没有类型。等等……
  • 我很抱歉M(T*),这部分是对的。但是构造t-&gt;*member [没有我上面说的参数列表] 只能用于类数据成员,不能用于类函数成员。
  • 这很奇怪,因为使用非常量成员函数,代码和库运行良好。

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


【解决方案1】:

正如Adam S 在 cmets 中指出的那样,当他尝试编译使用库 Selenethis simple code 时会发生此错误:

#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 标头中的代码。其中Class类的函数成员_register_member有两个重载:

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 函数成员(至少以您这样做的方式)。

【讨论】:

  • 非常感谢!添加第三个重载(具有与第二个相同的方法主体)使其工作。 (我不确定我是否可以接受这个作为答案,因为它诚然解决了我原来的问题,但我显然问错了问题......)
  • @AdamS 您可以在Meta Stack Overflow 询问有关它的问题。 :-)
  • 您也可以对第一个函数模板使用标签调度。这样,您不必为constvolatile 和引用限定符的所有组合定义模板。只需测试M 是否为函数类型。
【解决方案2】:

我应该提一下,对于现在查看此内容的人来说,这实际上是我的代码中的一个错误(实际上是一个疏忽),并且在发现问题后不久就得到了修复。

【讨论】:

    猜你喜欢
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 2020-03-24
    • 2011-03-04
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    相关资源
    最近更新 更多