std__invoke 的使用
文章目录
- std__invoke 的使用
- 1. `std::invoke` 的功能
- 2. 语法
- 3. 使用场景
- 1. 调用普通函数
- 2. 调用成员函数
- 3. 调用成员函数(通过指针或引用)
- 4. 调用函数对象(仿函数)
- 5. 调用 Lambda 表达式
- 4. `std::invoke` 的优势
- 5. 注意事项
- 6. 示例:综合应用
- 总结
std::invoke
是 C++17 引入的一个标准库函数,用于简化函数调用的语法。它允许你通过统一的接口调用普通函数、成员函数、函数对象或者 Lambda 表达式。这使得在处理不同类型的可调用对象时代码更加简洁和一致。
1. std::invoke
的功能
std::invoke
的目的是让你可以通过统一的方式来调用:
- 普通函数
- 成员函数
- 函数对象(仿函数)
- Lambda 表达式
2. 语法
template<typename _Callable, typename... _Args>invoke(_Callable&& __fn, _Args&&... __args){return std::__invoke(std::forward<_Callable>(__fn),std::forward<_Args>(__args)...);}
callable
是要调用的可调用对象(例如函数指针、成员函数指针、Lambda 表达式等)。args...
是传递给callable
的参数。
3. 使用场景
1. 调用普通函数
#include <iostream>
#include <functional>void print_hello(const std::string& name) {std::cout << "Hello, " << name << "!" << std::endl;
}int main() {std::invoke(print_hello, "World");return 0;
}
在这个例子中,std::invoke
调用了普通函数 print_hello
,并传递了一个参数 "World"
。
2. 调用成员函数
调用成员函数时,需要额外提供对象实例或对象指针。
#include <iostream>
#include <functional>class MyClass {
public:
void greet(const std::string& name) {std::cout << "Hello, " << name << "!" << std::endl;
}
};int main() {MyClass obj;std::invoke(&MyClass::greet, obj, "World");return 0;
}
在这个例子中,std::invoke
调用了 MyClass
的成员函数 greet
,并传递了对象 obj
和参数 "World"
。
3. 调用成员函数(通过指针或引用)
对于成员函数调用,你可以传递成员函数指针和对象指针(或者引用)。
#include <iostream>
#include <functional>class MyClass {
public:
void greet(const std::string& name) const {std::cout << "Hello, " << name << "!" << std::endl;
}
};int main() {MyClass obj;// 使用成员函数指针调用std::invoke(&MyClass::greet, obj, "World");// 或者可以传递对象指针MyClass* ptr = &obj;std::invoke(&MyClass::greet, ptr, "World");return 0;
}
4. 调用函数对象(仿函数)
std::invoke
同样适用于函数对象(仿函数)。
#include <iostream>
#include <functional>struct MyFunctionObject {
void operator()(const std::string& name) const {std::cout << "Hello, " << name << "!" << std::endl;
}
};int main() {MyFunctionObject obj;std::invoke(obj, "World"); // 调用仿函数return 0;
}
5. 调用 Lambda 表达式
std::invoke
也可以用于调用 Lambda 表达式。
#include <iostream>
#include <functional>int main() {auto greet = [](const std::string& name) {std::cout << "Hello, " << name << "!" << std::endl;};std::invoke(greet, "World"); // 调用 Lambda 表达式return 0;
}
4. std::invoke
的优势
- 简化代码:它可以统一调用不同类型的可调用对象(函数、成员函数、Lambda、函数对象等),避免了使用不同的调用方式。
- 类型推断:
std::invoke
会自动推断参数类型,无需显式指定。 - 支持成员函数:它特别适用于调用成员函数,避免了使用
.*
或->*
等复杂语法。
5. 注意事项
std::invoke
是一个通用工具,适用于各种类型的可调用对象。- 它的本质是通过反射机制来判断和调用对象。
6. 示例:综合应用
#include <iostream>
#include <functional>struct MyClass {
void greet(const std::string& name) {std::cout << "Hello, " << name << "!" << std::endl;
}static void static_greet(const std::string& name) {std::cout << "Hello from static function, " << name << "!" << std::endl;
}
};int main() {MyClass obj;// 调用成员函数std::invoke(&MyClass::greet, obj, "Alice");// 调用静态成员函数std::invoke(&MyClass::static_greet, "Bob");// 调用 Lambdaauto lambda = [](const std::string& name) {std::cout << "Hello from lambda, " << name << "!" << std::endl;};std::invoke(lambda, "Charlie");return 0;
}
总结
std::invoke
是一个灵活、强大的工具,它统一了函数、成员函数、函数对象和 Lambda 表达式的调用方式,使得 C++ 中的可调用对象使用变得更加简洁和一致。