gpt4 book ai didi

c++ - 为什么允许 shared_ptr

转载 作者:IT老高 更新时间:2023-10-28 21:48:15 25 4
gpt4 key购买 nike

This answer引用 N4082 ,这表明即将对 std::shared_ptr 进行的更改将允许 T[]T[N]变种:

Unlike the unique_ptr partial specialization for arrays, both shared_ptr<T[]> and shared_ptr<T[N]> will be valid and both will result in delete[] being called on the managed array of objects.

 template<class Y> explicit shared_ptr(Y* p);

Requires: Y shall be a complete type. The expression delete[] p, when T is an array type, or delete p, when T is not an array type, shall be well-formed, shall have well defined behavior, and shall not throw exceptions. When T is U[N], Y(*)[N] shall be convertible to T*; when T is U[], Y(*)[] shall be convertible to T*; otherwise, Y* shall be convertible to T*.

除非我弄错了,否则 Y(*)[N]只能通过获取数组的地址来形成,显然不能由 shared_ptr 拥有或删除.我也没有看到任何迹象表明 N以任何方式强制管理对象的大小。

允许T[N] 的动机是什么?句法?它是否产生任何实际好处,如果有,它是如何使用的?

最佳答案

您可以通过 std::shared_ptr 获得指向共享所有权的嵌套对象的指针。到包含对象。如果这个嵌套对象恰好是一个数组,而你想以数组类型访问它,你实际上需要使用 T[N]与合适的TN :

#include <functional>
#include <iostream>
#include <iterator>
#include <memory>
#include <queue>
#include <utility>
#include <vector>

using queue = std::queue<std::function<void()>>;

template <typename T>
struct is_range {
template <typename R> static std::false_type test(R*, ...);
template <typename R> static std::true_type test(R* r, decltype(std::begin(*r))*);
static constexpr bool value = decltype(test(std::declval<T*>(), nullptr))();
};

template <typename T>
std::enable_if_t<!is_range<T>::value> process(T const& value) {
std::cout << "value=" << value << "\n";
}

template <typename T>
std::enable_if_t<is_range<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 <typename P, typename T>
std::function<void()> make_fun(P const& p, T& value) {
return [ptr = std::shared_ptr<T>(p, &value)]{ process(*ptr); };
// here ----^
}

template <typename T, typename... M>
void enqueue(queue& q, std::shared_ptr<T> const& ptr, M... members) {
(void)std::initializer_list<bool>{
(q.push(make_fun(ptr, (*ptr).*members)), true)...
};
}

struct foo {
template <typename... T>
foo(int v, T... a): value(v), array{ a... } {}
int value;
int array[3];
std::vector<int> vector;
};

int main() {
queue q;
auto ptr = std::make_shared<foo>(1, 2, 3, 4);
enqueue(q, ptr, &foo::value, &foo::array, &foo::vector);
while (!q.empty()) {
q.front()();
q.pop();
}
}

在上面的代码中q只是一个简单的std::queue<std::function<void()>>但我希望你能想象它可能是一个线程池,将处理卸载到另一个线程。实际安排的处理也是微不足道的,但我再次希望您能想象它实际上是相当大量的工作。

关于c++ - 为什么允许 shared_ptr<T[N]>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40447401/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com