为何std::function可以接受数据成员指针?
关于std::function接受数据成员指针的疑问
以下代码提取并简化自
std::function相关实现示例:
#include <functional> #include <iostream> struct Foo { int num_; }; int main() { const Foo foo(314159); // 存储对数据成员访问器的调用 std::function<int(Foo const&)> f_num = &Foo::num_; std::cout << "num_: " << f_num(foo) << '\n'; }
疑问
为何上述代码中的std::function可以接受数据成员指针,且f_num(foo)能够正常运行?
原因解析
这是因为std::function的模板构造函数通过SFINAE机制,判断传入的可调用对象(包括数据成员指针)是否能匹配自身的签名。
你核查到的构造函数实现(以MSVC版本为例)如下:
#if _USE_FUNCTION_INT_0_SFINAE template <class _Fx, typename _Mybase::template _Enable_if_callable_t<_Fx&, function> = 0> #else // ^^^ _USE_FUNCTION_INT_0_SFINAE // !_USE_FUNCTION_INT_0_SFINAE vvv template <class _Fx, class = typename _Mybase::template _Enable_if_callable_t<_Fx&, function>> #endif // _USE_FUNCTION_INT_0_SFINAE function(_Fx _Func) { this->_Reset(_STD move(_Func)); }
其中_Enable_if_callable_t是核心判断逻辑:数据成员指针&Foo::num_的调用规则是**需要传入一个Foo类型的对象(或引用)**来获取成员值,而std::function<int(Foo const&)>的签名恰好是“接受const Foo&,返回int”,二者的调用行为完全匹配——调用f_num(foo)等价于直接访问foo.num_,这是C++标准允许的隐式适配:数据成员指针会被当作特殊的函数对象,接受类实例引用并返回成员取值。
std::function内部会通过_Reset函数将数据成员指针包装成符合自身签名的可调用实体,最终让f_num(foo)能够正常执行并返回成员值。
内容的提问来源于stack exchange,提问作者Zhang
相关产品推荐
相关产品推荐

