我真的很喜欢使用cmcstl2,这是 Ranges TS 的一个实现。我特别喜欢每个 STL 算法的可选投影。Invocable
类型像这样被转发(嗯......或不):(min_element.hpp)
template <ForwardIterator I, Sentinel<I> S,
class Comp = less<>, class Proj = identity>
requires
IndirectStrictWeakOrder<
Comp, projected<I, Proj>>()
I min_element(I first, S last, Comp comp = Comp{}, Proj proj = Proj{});
template <ForwardRange Rng, class Comp = less<>, class Proj = identity>
requires
IndirectStrictWeakOrder<
Comp, projected<iterator_t<Rng>, Proj>>()
safe_iterator_t<Rng>
min_element(Rng&& rng, Comp comp = Comp{}, Proj proj = Proj{})
{
return __stl2::min_element(__stl2::begin(rng), __stl2::end(rng),
__stl2::ref(comp), __stl2::ref(proj));
}
作为参考:range-v3库是这样实现的:(min_element.hpp)
struct min_element_fn {
template<typename I, typename S, typename C = ordered_less, typename P = ident,
CONCEPT_REQUIRES_(ForwardIterator<I>() && Sentinel<S, I>() &&
IndirectRelation<C, projected<I, P>>())>
I operator()(I begin, S end, C pred = C{}, P proj = P{}) const;
template<typename Rng, typename C = ordered_less, typename P = ident,
typename I = range_iterator_t<Rng>,
CONCEPT_REQUIRES_(ForwardRange<Rng>() &&
IndirectRelation<C, projected<I, P>>())>
range_safe_iterator_t<Rng> operator()(Rng &&rng, C pred = C{}, P proj = P{}) const
{
return (*this)(begin(rng), end(rng), std::move(pred), std::move(proj));
}
};
现在我试图理解这两种方法的区别和推理。我为什么要按Invocable
值取类型?为什么我不应该对这些类型使用完美转发?
与第一种方法相比,我更了解第二种方法,因为我了解按值获取接收器参数的方法。