在 class 方法上使用 std::apply
Using std::apply on class method
我试图编译以下内容(g++-11.2,C++20),但我得到:
error: no matching function for call to '__invoke(std::_Mem_fn<void (Foo::*)(int, double)>, std::__tuple_element_t<0, std::tuple<int, double> >, std::__tuple_element_t<1, std::tuple<int, double> >)'
1843 | return std::__invoke(std::forward<_Fn>(__f),
代码:
#include <iostream>
#include <tuple>
struct Foo
{
void bar(const int x, const double y)
{
std::cout << x << " " << y << std::endl;
}
void bar_apply()
{
// fails
std::apply(std::mem_fn(&Foo::bar), std::tuple<int, double>(1, 5.0));
}
};
int main()
{
Foo foo;
foo.bar_apply();
};
std::mem_fn(&Foo::bar)
不像捕获 lambda 那样存储 Foo
的实例:
std::apply([this](int x, double y) { return bar(x,y); },
std::tuple<int, double>(1, 5.0));
因此您需要在调用 mem_fn
对象时提供实例:
std::apply(std::mem_fn(&Foo::bar), std::tuple<Foo*, int, double>(this, 1, 5.0));
或更简单,使用 make_tuple
:
std::apply(std::mem_fn(&Foo::bar), std::make_tuple(this, 1, 5.0));
正如其他人所指出的,您需要一个实例来调用成员函数。您可以通过将函数调用包装到 lambda 表达式或通过元组参数来传递给 std::apply
。
不过,我建议 std::invoke
,这更适合这项任务。这样就不需要实例包装了。
#include <functional> // std::invoke
std::invoke(&Foo::bar, this, 1, 5.0);
我推荐使用 C++20 bind_front
,它更加轻量和直观。就像它的名字一样,成员函数需要一个特定的 class 对象来调用,所以你需要 bind this
指向 Foo::bar
.[=16 的指针=]
void bar_apply()
{
std::apply(std::bind_front(&Foo::bar, this), std::tuple<int, double>(1, 5.0));
}
我试图编译以下内容(g++-11.2,C++20),但我得到:
error: no matching function for call to '__invoke(std::_Mem_fn<void (Foo::*)(int, double)>, std::__tuple_element_t<0, std::tuple<int, double> >, std::__tuple_element_t<1, std::tuple<int, double> >)'
1843 | return std::__invoke(std::forward<_Fn>(__f),
代码:
#include <iostream>
#include <tuple>
struct Foo
{
void bar(const int x, const double y)
{
std::cout << x << " " << y << std::endl;
}
void bar_apply()
{
// fails
std::apply(std::mem_fn(&Foo::bar), std::tuple<int, double>(1, 5.0));
}
};
int main()
{
Foo foo;
foo.bar_apply();
};
std::mem_fn(&Foo::bar)
不像捕获 lambda 那样存储 Foo
的实例:
std::apply([this](int x, double y) { return bar(x,y); },
std::tuple<int, double>(1, 5.0));
因此您需要在调用 mem_fn
对象时提供实例:
std::apply(std::mem_fn(&Foo::bar), std::tuple<Foo*, int, double>(this, 1, 5.0));
或更简单,使用 make_tuple
:
std::apply(std::mem_fn(&Foo::bar), std::make_tuple(this, 1, 5.0));
正如其他人所指出的,您需要一个实例来调用成员函数。您可以通过将函数调用包装到 lambda 表达式或通过元组参数来传递给 std::apply
。
不过,我建议 std::invoke
,这更适合这项任务。这样就不需要实例包装了。
#include <functional> // std::invoke
std::invoke(&Foo::bar, this, 1, 5.0);
我推荐使用 C++20 bind_front
,它更加轻量和直观。就像它的名字一样,成员函数需要一个特定的 class 对象来调用,所以你需要 bind this
指向 Foo::bar
.[=16 的指针=]
void bar_apply()
{
std::apply(std::bind_front(&Foo::bar, this), std::tuple<int, double>(1, 5.0));
}