最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Why I can not construct mdspan from 2D C array? - Stack Overflow

programmeradmin0浏览0评论

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
  • The purpose of 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
Add a comment  | 

1 Answer 1

Reset to default 0

I 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] (aka arr[0]), you can only legally access arr[0][i] and not the rest of arr[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 just arr) 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.

发布评论

评论列表(0)

  1. 暂无评论