考虑以下代码:
#include <span>
struct A;
int foo(std::span<A> span);
通常,使用不完整类型作为模板参数实例化任何标准库模板会导致程序具有未定义的行为,除非该模板的规范中另有明确说明。
此规则不适用于此处,因为您所显示的代码中不会发生
std::span<A>
的隐式实例化。仅当类型需要完整或程序的含义取决于其完整性时,才会发生隐式实例化。
在非定义的函数声明中,函数参数通常不要求完整,因此声明
int foo(std::span<A> span);
不会导致
std::span<A>
的隐式实例化。
但是,在
[span.overview]/3中
std::span
的规范中有一个通用的要求,即元素类型必须完整。
我不清楚这是否打算在仅需要模板 ID 的有效性而不是实例化时应用。
但是,我认为将其应用于模板 ID 有效性没有意义。实现
std::span
以便在模板 ID 的有效性检查时可以观察到元素类型的完整性的唯一方法是让默认模板参数依赖于它,但是 std::span
没有任何依赖的默认值模板参数,或者通过在依赖于它的模板上添加约束,但是 std::span
也没有任何约束,并且我没有看到任何允许实现添加它们的内容。
所以我认为 [span.overview]/3 也仅适用于实例化。