Following code does not compile:
void fn(std::span<int> ) {}
int main() {
int arr[4][5]{};
fn(arr[0]);
std::mdspan msp(arr);
}
This is because std::mdspan is not constructible from a 2D C array. From what I see, this behavior was intentionally designed, as the deduction guide specifies the following:
requires(std::is_array_v<CArray> && std::rank_v<CArray> == 1)
However, I find this somewhat counterintuitive. Sometimes, I have a specific-size 2D array and would like to pass it to a generic function that operates on any 2D mdspan. It seems natural to me that this should be supported.
Following code does not compile:
void fn(std::span<int> ) {}
int main() {
int arr[4][5]{};
fn(arr[0]);
std::mdspan msp(arr);
}
This is because std::mdspan is not constructible from a 2D C array. From what I see, this behavior was intentionally designed, as the deduction guide specifies the following:
requires(std::is_array_v<CArray> && std::rank_v<CArray> == 1)
However, I find this somewhat counterintuitive. Sometimes, I have a specific-size 2D array and would like to pass it to a generic function that operates on any 2D mdspan. It seems natural to me that this should be supported.
Share Improve this question asked Feb 5 at 19:12 NoSenseEtAlNoSenseEtAl 30k31 gold badges147 silver badges321 bronze badges 1 |1 Answer
Reset to default 0I had a quick look at the proposal but didn't find anything. My best guess is that N-dimensional arrays in C/C++ are just inherently ugly.
Let's say you have a flat int arr[4*5];
. You can construct a 2D span from pointer &arr[0]
(aka just arr
) and two dimensions.
Now if you try create the same 2D span from int arr[4][5];
, what pointer do you pass and store?
If you pass
&arr[0][0]
(akaarr[0]
), you can only legally accessarr[0][i]
and not the rest ofarr[j][i]
.While I doubt compilers will choke on this at runtime, I believe they do validate this in
constexpr
contexts.Passing
&arr[0]
(aka justarr
) fixes that, but that's a different pointer type.std::mdspan
is flexible enough to allow customizing which pointer type is stored (via a custom accessor), so do we cook up a custom accessor for N-dim arrays?While I think it could be possible, accessors operate on 1D indices, so you would need to convert them back to N-dim indices to index the pointer, and so on.
A better solution would be to fix the language so that &arr[0][0]
can be used to access the entire arr[j][i]
, since people are doing this all the time anyway, and then the support can be added to std::mdspan
without the accessor nonsense.
mdspan
is to allow multi-dimensional manipulation from a one-dimensional array. You need to specify the template parameters as ` std::mdspan<int, std::extents<int, 4, 5>>`, which is just an illustration. – Rud48 Commented Feb 5 at 22:25