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

Late binding of template function types C++

我有一个这样的模板函数

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);

Live Demo

现在,如果您不知道 bind 处输入参数的类型,一种替代方法是使用通用 lambda 代替 std::bindstd::function

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

Live Demo

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

  1. 当你bind这样的成员函数时,你需要将一个引用或指针绑定到一个有效的对象(this)。
  2. bind 需要一个占位符,基本上断言在调用仿函数时将为 "place" 提供一个参数。
  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

注意:"type" 必须匹配(或转换为)std::function.

中指定的类型
std::function<void(const Foo&)> mp;

这是一个函数包装器,用于接受 const Foo& 并返回 void 的函数。为了支持 "unknown" 类型场景,通用 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));
};