<K> <K> 在三元中使用 std::greater 和 std::greater_equal

Using std::greater<K> and std::greater_equal<K> in a ternary

本文关键字:std lt greater gt equal 三元      更新时间:2023-10-16

我使用std::find_if,作为第三个参数,我想在std::bind2nd:中使用三元

std::bind2nd(foo ? std::greater<K>() : std::greater_equal<K>(), bar);

对于某些类型的CCD_ 3。CCD_ 4是CCD_。但这在语法上是不正确的,因为std::greater<K>()std::greater_equal<K>()是不同的类型。

理想情况下,我想删除三元(因为上面的内容在各种bar的循环中运行),并使用

auto predicate = foo ? std::greater<K>() : std::greater_equal<K>();
std::bind2nd(predicate, bar); /*this statement is in a loop*/

但这也不合法,因为predicate的类型在编译时是未知的。但std::bind2nd可以采用任何一种类型,所以我的想法是,可以成为实现我想要的东西的一种方式。有吗?

生成相同类型的操作数:

auto predicate = foo
             ? std::function<bool(K,K)>(std::greater<K>())
             : std::function<bool(K,K)>(std::greater_equal<K>());

演示

理由:

§5.16条件运算符[expr.cond]/p3

[…]如果第二个和第三个操作数具有不同的类型并且其中一个具有(可能是cv限定的)类类型,或者如果两者都是相同值类别和相同类型的glvalues(cv资格除外),则尝试将这些操作数中的每一个转换为另一个的类型。

std::greater<K>()std::greater_equal<K>()之间没有编译器可以自己执行的转换。

如果您坚持使用三元运算符,您可以将其中一个操作数强制转换为所需类型(这里我们强制使用std::function<bool(const K&, const K&)>),这也将是auto:推导的类型

auto predicate = foo ? std::greater<K>() : (std::function<bool(const K&, const K&)>) std::greater_equal<K>();   

lambda也可以做到这一点,可能更可读(并且不需要<functional>):

auto predicate = [&](const K& a) { return foo ? (a > bar) : (a >= bar); };
predicate(val);

注意:

bind2nd在C++11中已被弃用,您应该使用std::bind

std::bind(predicate, bar, std::placeholders::_1);

基于接受的答案,但我会颠倒操作顺序:

auto predicate = foo
             ? std::function<bool(K)>(std::bind(std::greater<K>(), bar))
             : std::function<bool(K)>(std::bind(std::greater_equal<K>(), bar));

bindfunction都有一些类型擦除开销,我怀疑按这个顺序它会小一些。这是因为bind的结果被指定为可以存储在std::function中的东西,但另一种方式更为巧合。