您可以获取一个指向共享所有权的嵌套对象的指针,std::shared_ptr
指向包含对象。如果该嵌套的对象恰好是一个数组,你要访问它作为一个数组类型,你实际上需要用合适的T
和N
使用T[N]
:
#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()>>
但我希望你可以想象它可能是一个线程池将处理卸载到另一个线程。实际预定的处理也是微不足道的,但我希望你可以想象它实际上是一些大量的工作。
没有任何东西可以保护您免受误用,但是一旦您拥有'shared_ptr',您可以遍历其元素而无需其他信息,所以就是这样。请注意,您仍然使用指向第一个元素的指针构造它,而不是指向数组本身的指针,因为您应该从'new T [N]'中获取指针。 –
@KerrekSB“... *因为你想要得到来自新的* T [N]的指针'”并不总是。请参阅[我的答案](http://stackoverflow.com/a/40447905/6394138)。 – Leon
当我进一步回顾N4082时,我发现'operator []'表示'i