是否可以确定可调用项是否为谓词(即返回bool)
Is it possible to determine if a callable is a predicate (i.e. returns bool)?
试图重写类似的谓词组合子
auto constexpr all = [](auto const&... predicates){
return [predicates...](auto const&... x){
return (predicates(x...) && ...);
};
};
(对此进行了一点概括(当使用具有不同arities/arguments的非谓词/谓词时,它会给出有意义的错误,我开始写这样的东西:
template<typename T, typename = void>
struct IsPredicate : public std::false_type {};
template<typename T>
struct IsPredicate<T, std::enable_if_t<std::is_same_v<bool, return_type_of_callable_T>, void>>
: public std::true_type {};
然后我盯着它看了一会儿。。。如果我甚至不知道如何调用函数,我该如何检查函数的返回类型?
我看到这个:
- 我甚至无法将
decltype(overloaded_predicate_function)
传递给IsPredicate
,因为模板类型推导不能用重载名称进行 - 即使我只谈论函数对象,第一个要点的问题也可能适用于
operator()
,以防它过载
所以我的问题是:是否有可能确定任意可调用函数的返回类型?
我最感兴趣的是C++17的答案,但是,为什么不呢?,我也想知道C++20的概念在这方面提供了什么。
所以我的问题是:是否有可能确定任意可调用函数的返回类型?
否。你只能在非常狭窄的情况下这样做:
- 可调用的是指向成员数据的指针/指向成员函数的指针
- 可调用的是指向函数的指针/引用
- 可调用的是一个函数对象,它具有一个非重载的函数调用运算符,该运算符不是模板,并且没有转换函数到函数指针/引用
就是这样。如果你有一个函数对象的调用运算符重载或是一个模板,你就无法真正弄清楚它的返回类型是什么。它的返回型可能取决于它的参数类型,你可能无法知道参数类型可能是什么。也许它是一个调用运算符模板,只接受一些你不知道的特定类型,但它是这些类型的谓词吗?
你能做的最好的事情就是推迟检查,直到你知道什么是论据。然后C++20已经为您提供了概念(谓词(:
inline constexpr auto all = []<typename... Ps>(Ps const&... predicates){
return [=]<typename... Xs>(Xs const&... x)
requires (std::predicate<Ps const&, Xs const&...> && ...)
{
return (std::invoke(predicates, x...) && ...);
};
};
请注意,您应该使用std::invoke
来允许指向成员的指针也作为谓词(这就是std::predicate
检查的内容(。
如果不指定参数类型(通常通过提供实际参数来完成(,就无法确定可调用函数的返回类型,因为返回类型可能取决于参数类型"decltype(potential_predicate(";不会起作用,但";decltype(potential_predicate(args…((";是另一回事。
第一个将是可调用表达式本身的类型(无论是指向函数的指针还是类类型或其他类型(,而第二个将生成可调用表达式的返回类型。
不能给你一个C++17的答案,但因为你也要求概念:
requires
表达式表示()
运算符过载,并返回一个bool
。我认为一个经典意义上的谓词需要两个参数,但这个概念也可以很容易地扩展到满足这个要求。
template<typename T>
concept IsPredicate =
requires(T a) {
{ a() } -> std::same_as<bool>;
};
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 写入向量<向量<bool>>
- 是否可以初始化不可复制类型的成员变量(或基类)
- 通过引用传递基元类型(如 int、bool)是否比按值传递有任何加速?还是会恶化时间/空间的使用
- 是否有一种替换C风格的Bool数组的标准方法
- Bool排序的插入函数,检查列表中是否已经存在int
- 载体<bool>是否违反了容器要求?
- 重新解释cast<是否安全;bool*>清空内存
- 使用类型"bool"类型的值初始化类型"int &"(非常量限定)的引用是否是一种黑客?
- 是否正确删除了 *bool 数组C++
- 赋值是否等同于 std::atomic <bool>的加载/存储
- 检查向量中的所有值是否为真的最优雅的方法是什么<bool>?
- 是否可以在bool中发送十进制值(8位)?如果是,那么怎么做?
- 在boost中是否有一个安全的bool习惯用法帮助器
- 是否可以在类定义之外以某种方式提供操作符bool强制转换的等量物?
- (bool)(i & 1) 和 i % 2 == 1 是否相同?
- 如何检查向量是否<bool>实际上是位而不是字节的向量?
- std::is_signed<bool>::value 是否保证返回 false?