模板函数类型C++的后期绑定

Late binding of template function types C++

本文关键字:绑定 C++ 函数 类型      更新时间:2023-10-16

我有一个类似的模板函数

template < typename T>
void Foo::func(T t)
{
}

和一个调用方函数

void FOO::func2()
{
    std::function<void(const Foo&)> mp;
    mp = std::bind(&Foo::func);
    ...
    ..
    ..
    //Finally
    mp();
}

这会导致编译错误,因为我没有指定类型mp = std::bind(&Foo::func);。问题是我当时不知道是什么类型的,但直到后来我才知道。有什么想法吗?

成员函数必须绑定到this,并且必须实例化模板:

std::function<void(const FOO&)> mp;
mp = std::bind(&FOO::func<const FOO&>, this, std::placeholders::_1);
mp(*this);

实时演示

现在,如果您不知道bind点的输入参数的类型,一种选择是使用通用lambdas而不是std::bindstd::function:

void FOO::func2() {
  auto mp = [this](auto t) { func(t); };
  ...
  mp(/*call here with what ever*/);
}

实时演示

代码中存在一些问题,导致编译失败。

  1. bind像这样的成员函数时,需要将引用或指针绑定到有效对象(this
  2. bind需要一个占位符,基本上是断言在调用函子时将为该"位置"提供一个参数
  3. 在调用std::function时,还需要提供一个适当的参数

因此,最终代码可能看起来像;

mp = std::bind(&Foo::func<const Foo&>, this, std::placeholders::_1);
//                                           ^^^ the placeholder
//                                     ^^^^ an object
//                       ^^^ template argument
mp(*this);
// ^^^ the argument for the std::function

注意:"类型"必须与std::function中指定的类型匹配(或转换为)。

std::function<void(const Foo&)> mp;

这是接受const Foo&并返回void的函数的函数包装器。为了支持"未知"类型场景,泛型lambda更适合此目的。

auto mp = [this](auto arg) { return this->func(arg); };

为了支持只移动类型(例如std::unique_ptr<>),lambda可以修改如下:;

auto mp = [this](auto&& arg) {
  return this->func(std::forward<decltype(arg)>(arg));
};