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

将std::vector设为模板函数局部变量后编译异常,哪个编译器处理正确?

问题描述

我编写了如下代码:

#include <iostream>
#include <span>
#include <vector>

std::vector v{1,2,3,4,5,6};

template <template <typename, std::size_t> class S>
S<int, std::dynamic_extent> GetSpan()
{
    return v;
}

int main()
{
    auto x = GetSpan<std::span>();
    return 0;
}

这段代码可被GCC和Clang正常编译。但当我将std::vector改为GetSpan()函数的局部变量,即:

template <template <typename, std::size_t> class S>
S<int, std::dynamic_extent> GetSpan()
{
    std::vector v{1,2,3,4,5,6};
    return v;
}

此时Clang仍可正常编译,但GCC会拒绝编译。请问哪个编译器的处理符合C++标准?原因是什么?

答案

GCC的处理符合C++标准,具体原因如下:

  • 当std::vector是GetSpan()的局部变量时,return v;语句中的v是自动存储期对象,在返回时会被视为亡值(xvalue),属于右值范畴。
  • std::span提供的容器构造函数(template<class Container> constexpr span(Container& cont);)要求参数是非const左值引用,而C++标准明确规定右值(包括亡值)无法绑定到非const左值引用。
  • 因此,用局部vector(亡值)隐式构造std::span的操作违反了标准规则,GCC拒绝编译是正确的。
  • Clang允许编译属于非标准行为,它错误地将return语句中的局部变量当作左值处理,绕过了右值无法绑定非const左值引用的限制。

内容的提问来源于stack exchange,提问作者Karen Baghdasaryan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:34:51