将指向数据成员的指针传递给 std::invoke 时有哪些用例和有用性?

What are the usecases and usefulness when passing pointer to data member to std::invoke?

本文关键字:有用性 invoke 数据成员 指针 std      更新时间:2023-10-16

我正在阅读有关 std::invoke 的 cpp 引用,并且想知道在哪些情况下我们需要将指向数据成员的指针和对象作为第二个参数作为第一个参数传递。

从 cpp 参考中,它指出:

使用参数参数调用可调用对象 f。如INVOKE(std::forward(f(, std::forward(args(...(。

其中 INVOKE(f, t1, t2, ..., tN( 定义如下:

然后第二点是:

否则,如果 N == 1 并且 f 是指向类的数据成员的指针

好的,让我们进一步看看这个,假设我正在使用std::thread(构造函数使用std::invoke(:

例如,我有点不清楚什么时候以这种方式使用线程是有用的(或者什么可以强制一个人(?

struct Foo {
Foo(int num) : num_(num) {}
void print_add(int i) const { std::cout << num_+i << 'n'; }
int num_;
void print_num(int i) const {
std::cout << i << 'n';
}
};
int main() {
const Foo foo(314159);
std::thread t(&Foo::num_, foo);
t.join();
return 0;
}  

以及如何将指向数据成员的指针与可调用的概念相关联?

您可能认为只有指向成员函数的指针才有用。也就是说,类似于:

struct Widget {
bool valid() const;
};
std::vector<Widget> widgets;
bool all_valid = std::ranges::all_of(widgets, &Widget::valid);

这将std::invoke指向每个Widget上的成员函数&Widget::valid的指针。但是,您可以轻松地构造Widget,以便valid只是一个标志,而不是成员函数。检查所有Widget是否都valid同样合理

struct Widget {
bool valid;
};
std::vector<Widget> widgets;
bool all_valid = std::ranges::all_of(widgets, &Widget::valid);

唯一的区别是,这std::invoke指向成员数据的指针,而不是指向成员函数的指针。但仍然有用。