我试图理解可以作为std :: invoke的第一个参数传递的概念和事物类型的层次结构。
我们考虑使用F
类型,以便至少存在Args
的{{1}}组合,std::is_invokable_v<F, Args...>
为true
。
问题[1]: F
可以是什么类型?
这是一个暂定的清单:
std::function_v<F>
等函数为true
std::function_v<std::remove_pointer_t<F>>
为true
std::function_v<std::remove_reference_t<F>>
为true
std::function_v<std::remove_pointer_t<std::remove_reference_t<F>>>
为true
std::is_member_function_pointer_v<F>
为true
std::is_member_function_pointer_t<std::remove_reference_t<F>>
为true
std::is_member_object_pointer_v<F>
为true
std::is_member_object_pointer_v<std::remove_reference_t<F>>
为true
std::is_class_v<F>
为true
且F::operator()
存在std::is_class_v<std::remove_reference_t<F>>
为true
且std::remove_reference_t<F>::operator()
存在std::is_union_v<F>
为true
且F::operator()
存在std::is_union_v<std::remove_reference_t<F>>
为true
且std::remove_reference_t<F>::operator()
存在std::remove_reference_t<F>
为闭包类型此列表是否正确?还有其他可行的选择吗?
问题[2]:闭包类型只是lambda表达式的类型,还是在C ++中有其他方式来创建一些被视为闭包类型的东西?
问题[3]:标准有时会讨论函数对象:问题1列表中的内容被视为函数对象?
问题[4]:执行以下操作:
std::is_class_v<F>
为true
且F::operator()
存在std::is_union_v<F>
为true
且F::operator()
存在属于标准中的特定概念(基本上是具有operator()
的东西)?如果不是,那么一个好的名称(例如,如果这样的东西在计算机科学或其他编程语言中有一个共同的名称)对于一个类型特征会检测一个类型是否满足列出的一个项目点?
答案 0 :(得分:3)
R(Args...)
,R(Args...) noexcept
,R(Args......)
和R(Args......) noexcept
的函数类型。operator()
成员(包括继承)的类类型; 对于#3,#4及其引用,还有一个额外的限定条件,即该类型中编码的cv资格和值类别必须与至少一个这样的函数兼容。
"Function object types"是可以使用通常的函数调用语法调用的对象类型,即#2-#4。指向成员的指针不符合条件,因为您无法使用()
调用它们。
根据定义,"callable type"是&#34;函数对象类型或指向成员的指针&#34;,即#2-#5。
函数类型和引用类型不是对象类型,因此既不是函数对象类型也不是可调用类型,但可以成为std::decay
应用程序的类型。
答案 1 :(得分:0)
我认为你错过了
的许多变化std::is_class_v<F>
为true
,并且F继承operator()
至于闭包和lambda,请注意C ++没有神奇的lambda。 Lambda只是类类型的对象,通过方便的语法创建。 std::bind
也会产生一个Callable
对象,这也可以被认为是一个闭包。但是,“封闭”是一个在C ++中没有确切含义的标签,不应该在列表中,正如Nicol Bolas在评论中所指出的那样。