对象方法的引用

  • 本文关键字:引用 方法 对象 c++
  • 更新时间 :
  • 英文 :


我想有一个对象的方法调用的引用。这在c++中可能吗?我应该搜索的专业名称是什么?我们可以提供一些带有预定值的参数吗?

下面的代码突出显示了我想使用的

struct Foo {
void barNoArgs();
void barMultArgs(int, float, bool);
};
Foo f;
auto& refToBarNoArgs = f.barNoArgs;
refToBarNoArgs(); // should call f.barNoArgs()

auto& refToBarMultArgs = f.barMultArgs(?, 3.14f, ?);
refToBarNoArgs(42, true); // should call f.barMultArgs(42, 3.14f, true)

我应该搜索的技术名称是什么?

这称为参数绑定,有时也称为部分函数

但首先,你应该知道你的两个例子是完全相同的问题。方法本质上是带有隐藏的第一个参数this的函数。

所以refToBarNoArgs是一个有0个参数的函数,它调用Foo::barNoArgs时第一个参数是预先填充的。refToBarNoArgs是一个接受2个参数的函数,调用Foo::barMultArgs时,第一个和第三个参数是预先填充的,第二个和第四个参数是自己的参数。

这里的关键是你的"参考";不能是c++意义上的引用。引用实际上并不存在(因为没有与引用本身相关联的对象)。在这两种情况下,我们都需要存储预填充参数的值,并管理它们的生存期。它必须是一个实际的对象,具有存储空间和生命周期,并且表现得像一个函数。这称为函子

该语言为我们提供了一点方便的语法糖,以便于同时创建这种函子的类型和单个实例:Lambdas.

auto refToBarNoArgs = [&f](){f.barNoArgs();};
refToBarNoArgs();
auto refToBarMultArgs = [&f](int i, bool b){f.barMultArgs(i, 3.14f, b);};
refToBarNoArgs(42, true);

如果您不熟悉lambda,请注意我示例中的[&f]。这意味着lambda通过引用捕获f。因此,它们的生存期(例如,存储在std::function<>中)不应超过f的生存期。

您也可以使用std::bind来有效地获得相同的东西。实际上,最终结果非常接近您的原始代码:

#include <functional>
struct Foo {
void barNoArgs();
void barMultArgs(int, float, bool);
};
int main() {
using namespace std::placeholders;  // for _1, _2, _3...
Foo f;
auto refToBarNoArgs = std::bind(&Foo::barNoArgs, &f);
refToBarNoArgs();
auto refToBarMultArgs = std::bind(&Foo::barMultArgs, &f, _1, 3.14f, _2);
refToBarNoArgs(42, true);
}

我个人觉得lambda更清晰。

从技术上讲,您可以获得指向成员函数的指针(成员函数指针),然后为对象调用该函数。

struct Foo {
void barNoArgs();
void barMultArgs(int, float, bool);
};
void foo() {
Foo f;
auto refToBarNoArgs = &Foo::barNoArgs;
(f.*refToBarNoArgs)();
}

固定(绑定)参数来创建一个新的函数,然后你可以用丢失的参数调用这个函数,这有点挑战性。我认为最简单的方法是使用lambda函数创建一个未命名的函数来包装成员并捕获对象。另一种选择是使用std::bind

#include <functional> // for std::bind
struct Foo {
void barNoArgs();
void barMultArgs(int, float, bool);
};
void foo() {
using namespace std;
using namespace std::placeholders;
Foo f;
auto b = bind( &Foo::barMultArgs, f, _1, 3.14f, _2);
auto l = [&f](auto const& x, auto const& y) {return f.barMultArgs(x,3.14f,y);};
b(42, true); // should call f.barMultArgs(42, 3.14f, true)
l(42, true); // should call f.barMultArgs(42, 3.14f, true)
}

相关内容

  • 没有找到相关文章

最新更新