c++中的std::invoke有什么用_c++统一调用可调用对象

6次阅读

std::invoke 统一了函数指针、成员函数指针、lambda 等可调用对象的调用方式,解决了泛型编程中语法不一致的问题;通过 std::invoke(callable, args…)可简化模板中对不同可调用对象的处理,提升代码通用性与安全性。

c++ 中的 std::invoke 有什么用_c++ 统一调用可调用对象

在 C ++ 中,std::invoke 是一个用于统一调用各种可调用对象的 工具,它让函数指针、成员函数指针、函数对象(仿函数)、lambda 表达式等都能以一致的方式被调用。这个功能从 C++17 开始引入,极大简化了泛型编程中对不同调用形式的处理。

统一调用语法:解决什么问题?

在模板编程中,我们常常需要处理多种类型的可调用对象,比如:

  • 普通函数
  • lambda 表达式
  • std::function 包装的对象
  • 成员函数指针
  • 重载了 operator() 的类对象

如果没有 std::invoke,针对成员函数指针的调用就需要特殊语法,比如 obj.*func 或 (obj.*func)(),而普通函数则是 func()。这种差异在写通用代码时非常麻烦。std::invoke 就是为了抹平这些语法差异而设计的。

基本用法示例

std::invoke 的语法很简单:

立即学习C++ 免费学习笔记(深入)”;

std::invoke(callable, args…);

来看几个例子:

调用普通函数或 lambda:

int add(int a, int b) {return a + b;}
auto result = std::invoke(add, 2, 3); // result == 5

auto lambda = [](int x){return x * x;};
result = std::invoke(lambda, 4); // result == 16

调用成员函数:

struct Person {
  std::string name;
  std::string get_name() const { return name;}
};

Person p{“Alice”};
std::string n = std::invoke(&Person::get_name, p); // 正确调用成员函数

这里 &Person::get_name 是成员函数指针,p 是对象实例,std::invoke 自动处理了 .*

调用数据成员(读取字段):

std::string name = std::invoke(&Person::name, p); // name == “Alice”

这相当于直接访问 p.name,但在泛型场景下很有用。

在泛型代码中的实际价值

std::invoke 最大的优势体现在模板中。比如你写一个通用的“延迟调用”函数:

template
auto call_later(Callable&& c, Args&&… args) {
  // 做一些准备工作 …
  return std::invoke(std::forward(c),
    std::forward(args)…);
}

这个函数能正确处理:

  • 普通函数调用
  • lambda 调用
  • 成员函数通过对象或指针调用
  • 甚至对成员变量的“调用”(获取值)

无需为每种情况写特化版本。

基本上就这些。std::invoke 让 C++ 的泛型调用变得更简洁、更安全,是现代 C++ 中处理可调用对象的推荐方式。

以上就是

text=ZqhQzanResources