You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在非模板函数中存储并传递std::mdspan至结构体?

关于std::mdspan存储到结构体及非模板函数传递的问题

问题点

  • 能否将std::mdspan实例存入结构体并传递给函数,且无需将目标函数改为模板实现?
  • 当前代码通过dummy对象配合decltype获取std::mdspan类型,是否有更直接的方式规避这种写法?
  • 尝试直接指定std::mdspan<float*,int,int>类型时触发编译错误,错误信息如下:
Z:/compilers/msvc/14.41.33923-14.41.33923.0/include\mdspan(1075): error C2903: 'mapping': symbol is neither a class template nor a function template
Z:/compilers/msvc/14.41.33923-14.41.33923.0/include\mdspan(1075): note: the template instantiation context (the oldest one first) is
<source>(6): note: see reference to class template instantiation 'std::mdspan<float *,int,int,std::default_accessor<float *>>' being compiled
Z:/compilers/msvc/14.41.33923-14.41.33923.0/include\mdspan(1159): note: see reference to class template instantiation 'std::_Mdspan_mapping_base<_Extents,_LayoutPolicy>' being compiled
        with
        [
            _Extents=int,
            _LayoutPolicy=int
        ]
etc...

原始代码示例

#include <iostream>
#include <vector>
#include <mdspan>

int* dummy;

struct Container {
    decltype(std::mdspan(dummy, 0, 0)) array2d;
};

void foo(Container cont) {
    std::cout << cont.array2d[std::array{ 1, 1 }];
}

int main()
{
    std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7 };

    auto array2d = std::mdspan(v.data(), 2, 4);

    Container container;

    container.array2d = array2d;

    foo(container);
}

解答

1. 直接指定类型报错的原因

std::mdspan的模板参数不是直接填维度数值,第二个模板参数要求是符合Extents概念的类型(比如std::extents或std::dextents),而非原始的int。你直接传入两个int,编译器会把它们当成Extents和LayoutPolicy模板参数,而int不满足这两个模板参数的要求,导致内部mapping相关模板实例化失败,触发编译错误。

2. 规避dummy+decltype的写法

直接明确指定std::mdspan的正确模板参数即可:

  • 动态维度(运行时确定大小):用std::dextents<int, N>,其中N是维度数。比如二维动态数组的类型是std::mdspan<int*, std::dextents<int, 2>>
  • 固定维度(编译时确定大小):用std::extents<int, D1, D2,...>,比如固定2行4列的数组类型是std::mdspan<int*, std::extents<int, 2, 4>>

修改后的Container结构体示例:

struct Container {
    // 动态二维int数组的mdspan类型
    std::mdspan<int*, std::dextents<int, 2>> array2d;
};

3. 非模板函数传递的可行性

完全可以。只要结构体中mdspan的类型是明确固定的,函数foo直接接受Container类型即可,不需要改成模板函数。原始代码中Container的类型已经通过decltype推导确定,所以foo可以正常工作;修改为直接指定类型后,同样可以用非模板函数传递。

完整修改后的代码

#include <iostream>
#include <vector>
#include <mdspan>
#include <array>

struct Container {
    std::mdspan<int*, std::dextents<int, 2>> array2d;
};

void foo(Container cont) {
    std::cout << cont.array2d[std::array{1, 1}] << std::endl;
}

int main()
{
    std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7 };
    auto array2d = std::mdspan(v.data(), 2, 4);

    Container container;
    container.array2d = array2d;

    foo(container);
}

内容的提问来源于stack exchange,提问作者Damir Tenishev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 22:40:00