为什么 std::function 接受数据成员指针?

问题描述 投票:0回答:1

这段代码是从

std::function

中提取和简化的
#include <functional>
#include <iostream>
 
struct Foo
{
    int num_;
};

int main()
{
    const Foo foo(314159);
     // store a call to a data member accessor
    std::function<int(Foo const&)> f_num = &Foo::num_;
    std::cout << "num_: " << f_num(foo) << '\n';
}

为什么这个

std::function
接受指向数据成员的指针,为什么
f_num(foo)
完全有效?

我检查过它使用了这个构造函数:

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

https://godbolt.org/z/vTKfsWMhG

c++ stl c++20 std-function
1个回答
2
投票

std::function
构造函数接受指向数据成员的指针,因为它是Callable。这之所以有效,是因为引擎盖下有
std::invoke

发生的事情是这样的:

  • std::function
    构造函数获取指向数据成员的指针。
  • 当您调用
    f_num(foo)
    时,它使用
    std::invoke
    ,它知道如何处理指向数据成员的指针。在这种情况下,它将指针视为一个函数,该函数接受一个对象并返回引用的数据成员。
  • 这使您可以执行按特定班级成员排序等操作,从而提供了一种与班级成员一起工作的通用方式。

以这种方式使用成员指针符合 C++ 标准,并允许在代码中使用一些强大的模式。

© www.soinside.com 2019 - 2024. All rights reserved.