【发布时间】: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->*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->*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成员函数甚至是普通函数,两者都可以分配给“简单”函数指针并与之一起使用。
标签: c++ c++11 function-pointers member-function-pointers