How should I define a std::function variable with default arguments?

后端 未结 4 1070
有刺的猬
有刺的猬 2021-02-07 08:48

To set a std::function variable to a lambda function with default argument I can use auto as in:

auto foo = [](int x = 10){cout << x <<          


        
4条回答
  •  野趣味
    野趣味 (楼主)
    2021-02-07 09:38

    The signature in std::function is based on how you plan to call it and not on how you construct/assign it. Since you want to call it two different ways, you'll need to store to different std::function objects, as in:

    struct Call
    {
        template
        explicit Call(F f) : zero_(f), one_(std::move(f)) {}
    
        void operator()() { zero_(); }
        void operator()(int i) { one_(i); }
    
        std::function    zero_;
        std::function one_;
    };
    

    Alternatively, you can do the type erasure yourself (what std::function does behind the scenes) to only store the lambda once, as in:

    class TECall
    {
        struct Concept
        {   
            Concept() = default;
            Concept(Concept const&) = default;
            virtual ~Concept() = default;
    
            virtual Concept* clone() const = 0;
    
            virtual void operator()() = 0;
            virtual void operator()(int) = 0;
        };  
    
        template
        struct Model final : Concept
        {   
            explicit Model(T t) : data(std::move(t)) {}
            Model* clone() const override { return new Model(*this); }
    
            void operator()() override { data(); }
            void operator()(int i) override { data(i); }
    
            T data;
        };  
    
        std::unique_ptr object;
    
    public:
        template
        TECall(F f) : object(new Model(std::move(f))) {}
    
        TECall(TECall const& that) : object(that.object ? that.object->clone() : nullptr) {}
        TECall(TECall&& that) = default;
        TECall& operator=(TECall that) { object = std::move(that.object); return *this; }
    
        void operator()() { (*object)(); }
        void operator()(int i) { (*object)(i); }
    };
    

提交回复
热议问题