#include <range/v3/all.hpp>#include <iostream>#include <vector>int main() { using @R_403_6889@space ranges; auto const N = 10; std::vector<int> v; v.reserve(N); v |= action::push_back(vIEw::iota(0,N)); random_shuffle(v); copy(v,ostream_iterator<>(std::cout,","));}
Live Example.
但是,我更愿意使用假设的动作:: random_shuffle()来扩展管道
v |= action::push_back(vIEw::iota(0,N)) | action::random_shuffle();
这是我尝试编写这样的动作(不幸的是,编写新的range-v3代码比使用库更加冗长)
#include <functional> // bind,placeholders::_1@R_403_6889@space ranges{ inline @R_403_6889@space v3 { /// \addtogroup group-actions /// @{ @R_403_6889@space action { struct random_shuffle_fn { private: frIEnd action_access; static auto bind(random_shuffle_fn random_shuffle) RANGES_DECLTYPE_auto_RETURN ( std::bind(random_shuffle,std::placeholders::_1) ) template<type@R_403_6889@ Gen> static auto bind(random_shuffle_fn random_shuffle,Gen && rand) RANGES_DECLTYPE_auto_RETURN ( std::bind(random_shuffle,std::placeholders::_1,bind_forward<Gen>(rand)) ) public: struct ConceptImpl { template<type@R_403_6889@ Rng,type@R_403_6889@ I = range_iterator_t<Rng>> auto requires_(Rng&&) -> decltype( concepts::valID_expr( concepts::model_of<concepts::RandomAccessRange,Rng>(),concepts::is_true(Permutable<I>()) )); }; template<type@R_403_6889@ Rng> using Concept = concepts::models<ConceptImpl,Rng>; template<type@R_403_6889@ Rng,CONCEPT_REQUIRES_(Concept<Rng>())> Rng operator()(Rng && rng) const { ranges::random_shuffle(rng); return std::forward<Rng>(rng); } template<type@R_403_6889@ Rng,type@R_403_6889@ Gen,CONCEPT_REQUIRES_(Concept<Rng>())> Rng operator()(Rng && rng,Gen && rand) const { ranges::random_shuffle(rng,std::forward<Gen>(rand)); return std::forward<Rng>(rng); } #ifndef RANGES_DOXYGEN_INVOKED template<type@R_403_6889@ Rng> voID operator()(Rng &&) const { CONCEPT_ASSERT_MSG(RandomAccessRange<Rng>(),"The object on which action::random_shuffle operates must be a model of the " "RandomAccessRange concept."); using I = range_iterator_t<Rng>; CONCEPT_ASSERT_MSG(Permutable<I>(),"The iterator type of the range passed to action::random_shuffle must allow its " "elements to be permuted; that is,the values must be movable and the " "iterator must be mutable."); } #endif }; /// \ingroup group-actions /// \relates sort_fn /// \sa `action` @R_403_6889@space { constexpr auto&& random_shuffle = static_const<action<random_shuffle_fn>>::value; } } /// @} }}
Live Example无法编译,因为某些operator()深藏在某处未找到.
据我所见,我忠实地从类似的代码中转换了上述代码,例如action :: sort().唯一的区别是random_shuffle()有两个重载(一个采用随机生成器),而所有其他动作(包括sort)都有一个重载,其额外参数的默认值(比较器,谓词,投影仪等) .这转换为上面的random_shuffle_fn的两个bind()静态成员函数,而所有其他 *** 作只有一个bind()重载.
问题:如何为random_shuffle编写range-v3动作?
解决方法 你有两个不明确的random_shuffle_function :: operator()(Rng&&)重载,你的“错误捕获”重载需要被限制为只接受那些正确的重载拒绝的参数(我们真的需要C Concepts所以我再也没有了到SFINAE约束重载):#ifndef RANGES_DOXYGEN_INVOKEDtemplate<type@R_403_6889@ Rng,CONCEPT_REQUIRES_(!Concept<Rng>())>voID operator()(Rng &&) const{ CONCEPT_ASSERT_MSG(RandomAccessRange<Rng>(),"The object on which action::random_shuffle operates must be a model of the " "RandomAccessRange concept."); using I = range_iterator_t<Rng>; CONCEPT_ASSERT_MSG(Permutable<I>(),"The iterator type of the range passed to action::random_shuffle must allow its " "elements to be permuted; that is,the values must be movable and the " "iterator must be mutable.");}#endif
此外,您需要管道 *** 作:: random_shuffle:
v |= action::push_back(vIEw::iota(0,N)) | action::random_shuffle;
DEMO
总结以上是内存溢出为你收集整理的c – 如何为random_shuffle编写range-v3动作?全部内容,希望文章能够帮你解决c – 如何为random_shuffle编写range-v3动作?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)