Is there any other way to receive a reference to an array from function returning except using a pointer?
Here is my code.
int ia[] = {1, 2, 3};
decl
-
To answer this question one can design a solution around std::reference_wrapper. This code compiles and runs.
#pragma once
#include
#include
#include
#include
namespace {
///
/// some generic utility function
/// with argument declared as
/// native array reference
/// for testing purposes only
///
template
inline void array_util_function( T (&arr_ref) [N] ) {
auto random = [](int max_val, int min_val = 1) -> int {
// use current time as seed for
// random generator, but only once
static auto initor = []() {
std::srand((unsigned)std::time(nullptr)); return 0;
}();
return min_val + std::rand() / ((RAND_MAX + 1u) / max_val);
};
for (auto & element : arr_ref) {
element = random(N);
}
}
// the key abstraction
template
using native_arr_ref_wrapper = std::reference_wrapper;
template
constexpr std::size_t array_size(T(&arr_ref)[N]) {
return N;
}
// return the size of the native array
// contained within
template
constexpr std::size_t array_size(native_arr_ref_wrapper & narw_) {
return array_size(narw_.get());
}
///
/// returns std::reference_wrapper copy
/// that contains reference to native array
/// in turn contained inside the std::array
/// argument
///
template
inline auto
native_arr_ref(const std::array & std_arr)
-> native_arr_ref_wrapper
{
using nativarref = T(&)[N];
return std::ref(
(nativarref)*(std_arr.data())
);
}
///
/// returns std::reference_wrapper copy
/// that contains reference to native array
///
template
inline auto
native_arr_ref(const T (& native_arr)[N] )
-> native_arr_ref_wrapper
{
using nativarref = T(&)[N];
return std::ref(
(nativarref)*(native_arr)
);
}
auto printarr = [](auto arr_ref, const char * prompt = "Array :") {
printf("\n%s:\n{ ", prompt);
int j = 0;
// use the array reference
// to see the contents
for (const auto & element : arr_ref.get()) {
printf(" %d:%d ", j++, element);
}
printf(" }\n");
};
// arf == native array reference
void test_ () {
using std::array;
// the arf type is
// std::reference_wrapper
auto arf = native_arr_ref(array{});
// the arf type is same here
// but made from a native array
auto ar2 = native_arr_ref({ 0,1,2,3,4,5,6,7,8,9 });
printarr(ar2);
// notice how argument to native_arr_ref()
// does not exist here any more
// but, wrapper contains the copy
// of the native array
// type is here: int[10]&
auto & native_arr_ref = arf.get();
// due to array type decay
// the type is here: int *
auto native_arr_ptr = arf.get();
// size_t
const auto size = array_size(arf);
// this function requires
// native array as argument
// this is how we use arf in place of
// native arrays
array_util_function(arf.get());
printarr(arf);
}
}
- 热议问题