c – 如何为random_shuffle编写range-v3动作?

c – 如何为random_shuffle编写range-v3动作?,第1张

概述使用 range-v3 library(由@EricNiebler),使得编写算法代码更加紧凑,例如这是如何生成一堆随机数: #include <range/v3/all.hpp>#include <iostream>#include <vector>int main() { using namespace ranges; auto const N = 10; 使用 range-v3 library(由@EricNIEbler),使得编写算法代码更加紧凑,例如这是如何生成一堆随机数:
#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动作?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1239838.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存