Why allow shared_ptr?

前端 未结 2 1030
渐次进展
渐次进展 2021-02-18 15:44

This answer cites N4082, which shows that the upcoming changes to std::shared_ptr will allow both T[] and T[N] variants:

2条回答
  •  广开言路
    2021-02-18 16:07

    You can get a pointer to a nested object sharing ownership with a std::shared_ptr to the containing object. If this nested object happens to be an array and you want to access it as an array type, you actually need to use T[N] with suitable T and N:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    using queue = std::queue>;
    
    template 
    struct is_range {
        template  static std::false_type test(R*, ...);
        template  static std::true_type test(R* r, decltype(std::begin(*r))*);
        static constexpr bool value = decltype(test(std::declval(), nullptr))();
    };
    
    template 
    std::enable_if_t::value> process(T const& value) {
        std::cout << "value=" << value << "\n";
    }
    
    template 
    std::enable_if_t::value> process(T const &range) {
        std::cout << "range=[";
        auto it(std::begin(range)), e(std::end(range));
        if (it != e) {
            std::cout << *it;
            while  (++it != e) {
                std::cout << ", " << *it;
            }
        }
        std::cout << "]\n";
    }
    
    template 
    std::function make_fun(P const& p, T& value) {
        return [ptr = std::shared_ptr(p, &value)]{ process(*ptr); };
                                // here ----^
    }
    
    template 
    void enqueue(queue& q, std::shared_ptr const& ptr, M... members) {
        (void)std::initializer_list{
            (q.push(make_fun(ptr, (*ptr).*members)), true)...
            };
    }
    
    struct foo {
        template 
        foo(int v, T... a): value(v), array{ a... } {}
        int value;
        int array[3];
        std::vector vector;
    };
    
    int main() {
        queue q;
        auto ptr = std::make_shared(1, 2, 3, 4);
        enqueue(q, ptr, &foo::value, &foo::array, &foo::vector);
        while (!q.empty()) {
            q.front()();
            q.pop();
        }
    }
    

    In the above code q is just a simple std::queue> but I hope you can imagine that it could be a thread-pool off-loading the processing to another thread. The actually scheduled processing is also trivial but, again, I hope you can imagine that it is actually some substantial amount of work.

提交回复
热议问题