指向实例的成员函数而不是类的指针

Posted

技术标签:

【中文标题】指向实例的成员函数而不是类的指针【英文标题】:Pointer to member function of instance instead of class 【发布时间】:2021-07-29 08:45:35 【问题描述】:

当我根据某种条件获得指向成员函数的指针然后调用该函数时,我有以下类。

class Test

public:
    bool isChar(char ch)  return (ch >= 'a' && ch <= 'z'); 
    bool isNumeric(char ch)  return (ch >= '0' && ch <= '0'); 

    enum class TestType
    
        Undefined,
        Char,
        Numeric,
        AnotherOne,
    ;

    bool TestFor(TestType type, char ch)
    
        typedef bool (Test::*fptr)(char);
        fptr f = nullptr;
        switch(type)
        
            case TestType::Char:
                f = &Test::isChar;
                break;
            case TestType::Numeric:
                f = &Test::isNumeric;
                break;
            default: break;
        

        if(f != nullptr)
        
            return (this->*f)(ch);
        

        return false;
    
;

但实际上我不喜欢这种语法。有没有办法替换

(this->*f)(ch)

f(ch)

?

在我的真实代码中,这个函数足够大,而且还不清楚(this-&gt;*f) 是什么。我正在寻找一些c++11 解决方案。我知道std::function,如果找不到解决方案,我会使用它。

更新

我决定使用的解决方案,如果突然有人需要它:(感谢@StoryTeller - Unslander Monica)

bool TestFor(TestType type, char ch)
        
    bool(Test::* fptr)(char) = nullptr;
    switch(type)
    
        case TestType::Char:
            fptr = &Test::isChar;
            break;
        case TestType::Numeric:
            fptr = &Test::isNumeric;
            break;
        default: break;
    

    if(fptr != nullptr)
    
        auto caller = std::mem_fn(fptr);
        return caller(this, ch);
    

    return false;

【问题讨论】:

“我不喜欢这种语法” - 也许是这样,但这种语法的设计精确让你可以做你想做的事正在做。关于“(this-&gt;*f) 是什么还不是很清楚。” - 任何人都清楚 (a) 知道 C++,并且 (b) 知道指向成员访问的指针是什么。后者对于真正正在发生的事情的正确上下文很重要。试图对正在阅读代码的人隐藏这似乎会适得其反。也就是说,您可以将std::function 或 old(ish)-school 和 std::bind 放在一起。它不会让代码变得“更好”,但也许你会喜欢它的语法。 在 C++17 中,std::invoke(f, this, ch)? 顺便说一句,isChar 对于 EBCDIC 是错误的。 (范围a-z 不保证是连续的)。 是的,std::invoke 可能是一个解决方案,但我的目标板有点受限,仅支持 c++11 我刚刚注意到您的示例代码函数不访问this,而是仅评估参数。在这种情况下,另一种解决方案是static 成员函数甚至是普通函数,两者都可以分配给“简单”函数指针并与之一起使用。 【参考方案1】:

如果语法让您如此困扰,您可以随时使用std::mem_fn 为成员函数生成一个廉价的一次性包装器。

auto caller = std::mem_fn(f);
caller(this, ch);

【讨论】:

很好,解决方案。至少,更优雅。让我感到羞耻的是,我不知道std::mem_fn。我想这就是我要使用的。非常感谢!

以上是关于指向实例的成员函数而不是类的指针的主要内容,如果未能解决你的问题,请参考以下文章

指向虚拟成员函数的指针是不是具有可比性?

C++ 指向具有匹配函数签名的任何类的成员函数的指针

c++类的成员函数指针如何转为普通指针

C++函数指针与成员函数指针

C++中怎么获取类的成员函数的函数指针

C++基础之类和对象二