为何无法用临时std::array<int>构造std::span<int>?
为什么std::array无法隐式转换为std::span?
你遇到的问题核心在于:你预期调用的std::span构造函数(接受std::array的重载)是**显式(explicit)**的,而函数参数传递属于隐式类型转换场景,编译器无法自动使用这个构造函数完成转换。
关键细节
你提到的构造函数原型在C++标准中是这样定义的(注意explicit关键字):
template< class U, std::size_t N > constexpr explicit span( const std::array<U, N>& arr ) noexcept;
这个explicit修饰符意味着它只能用于显式类型转换(比如直接构造、static_cast),不能用于隐式转换场景——比如你代码里直接把std::array作为参数传给期望std::span的函数。
你分析的约束条件(extent == dynamic_extent、类型匹配)确实都满足,但这些是构造函数参与重载决议的前提,而explicit是限制它能否被隐式调用的关键。
修复方案
只需要显式构造std::span即可:
#include <array> #include <span> void foo(std::span<int>); int main() { // 显式构造std::span foo(std::span<int>(std::array<int, 3>{})); // 或者更简洁的类模板参数推导(C++17及以上) // foo(std::span{std::array<int, 3>{}}); }
补充说明
标准将这个构造函数设为explicit是为了避免意外的隐式转换导致的悬空引用风险——比如如果隐式把一个局部数组转成std::span,后续数组销毁后span就会变成野指针。即使你这里用的是临时数组(本身也会导致span悬空,调用foo时临时数组已经销毁),标准依然统一要求显式构造来明确开发者的意图。
内容的提问来源于stack exchange,提问作者Jan Schultke
相关产品推荐
相关产品推荐

