我正在阅读有关 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
指向成员数据的指针,而不是指向成员函数的指针。但仍然有用。