This answer cites N4082, which shows that the upcoming changes to std::shared_ptr
will allow both T[]
and T[N]
variants:
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.