C++ 具名要求:可调用 (Callable)
来自cppreference.com
可调用 (Callable) 类型是可应用 INVOKE 操作(例如用于 std::function、std::bind 和 std::thread::thread)的类型。可以用库函数 std::invoke 显式进行此操作。 (C++17 起)
要求
若满足下列条件,则类型 T
满足可调用 (Callable)
给定
-
T
类型的对象f
- 适合的实参类型列表
ArgTypes
- 适合的返回类型
R
则下列表达式必须合法:
表达式 | 要求 |
---|---|
INVOKE<R>(f, std::declval<ArgTypes>()...) | 该表达式在不求值语境中良构 |
其中 INVOKE<R>(f, t1, t2, ..., tN),若 R
是可有 cv 限定的 void,则定义为 static_cast<void>(INVOKE(f, t1, t2, ..., tN)),否则为 INVOKE(f, t1, t2, ..., tN),隐式转换成 R
其中 INVOKE(f, t1, t2, ..., tN) 定义如下:
- 若
f
是类T
的成员函数指针:
- 若 std::is_base_of<T, std::remove_reference_t<decltype(t1)>>::value 为 true,则 INVOKE(f, t1, t2, ..., tN) 等价于 (t1.*f)(t2, ..., tN)
- 否则,若 std::remove_cvref_t<decltype(t1)> 为 std::reference_wrapper 的特化,则 INVOKE(f, t1, t2, ..., tN) 等价于 (t1.get().*f)(t2, ..., tN)
- 否则,若
t1
不满足前述条件,则 INVOKE(f, t1, t2, ..., tN) 等价于 ((*t1).*f)(t2, ..., tN)。
- 否则,若 N == 1 且
f
是类T
的数据成员指针:
- 若 std::is_base_of<T, std::remove_reference_t<decltype(t1)>>::value 为 true,则 INVOKE(f, t1) 等价于 t1.*f
- 否则,若 std::remove_cvref_t<decltype(t1)> 是 std::reference_wrapper 的特化,则 INVOKE(f, t1) 等价于 t1.get().*f
- 否则,若
t1
不满足前述条件,则 INVOKE(f, t1) 等价于 (*t1).*f
- 否则,INVOKE(f, t1, t2, ..., tN) 等价于 f(t1, t2, ..., tN)(即
f
是一个函数对象 (FunctionObject) )
注解
对于成员函数指针和数据成员指针,t1
可以是一个常规指针或一个重载了 operator*
的类的对象,例如 std::unique_ptr 或 std::shared_ptr。
数据成员指针为可调用 (Callable) ,尽管并不发生函数调用。
标准库
此外,下列标准库设施接受任何可调用 (Callable) 类型(不仅是函数对象 (FunctionObject) )
(C++11) |
包装具有指定函数调用签名的任意可复制构造类型的可调用对象 (类模板) |
(C++23) |
包装具有指定函数调用签名的任意类型的可调用对象 (类模板) |
(C++11) |
绑定一或多个实参到函数对象 (函数模板) |
(C++20) |
按顺序绑定一定数量的参数到函数对象 (函数模板) |
(C++11) |
可复制构造 (CopyConstructible) 且可复制赋值 (CopyAssignable) 的引用包装器 (类模板) |
(C++11)(C++20 中移除)(C++17) |
推导以一组实参调用一个可调用对象的结果类型 (类模板) |
(C++11) |
管理单独的线程 (类) |
(C++20) |
有自动合并和取消支持的 std::thread (类) |
(C++11) |
仅调用函数一次,即使从多个线程调用 (函数模板) |
(C++11) |
异步运行一个函数(有可能在新线程中执行),并返回保有其结果的 std::future (函数模板) |
(C++11) |
打包一个函数,存储其返回值以进行异步获取 (类模板) |
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
DR | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
LWG 2219 | C++11 | 不可能以 reference_wrapper 为对象表达式 INVOKE 成员指针
|
检测并处理 reference_wrapper
|
LWG 2420 | C++11 | 当 R 为 void 时,要求从结果到 void 的不可能的隐式转换
|
当 R 为 cv void 时结果可显式转换为 void
|
参阅
检查类型能否以给定的实参类型调用(如同以 std::invoke) (类模板) | |
(C++20) |
指定能以给定的一组实参类型调用的可调用类型 (概念) |