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

为何带std::integral的auto&&运算符[]无法接受左值?

为什么带std::integral约束的auto&&万能引用只能接受右值?

按规则,auto&&应与模板中的T&&类似,代表万能引用而非右值引用,但某JSON库中json_t类的operator[]仅能接受右值,传入左值会触发错误:no operator "[]" matches these operands。相关代码如下:

#include <variant>

struct json_t
{
    using array_t = std::vector<json_t>;
    using object_t = std::map<std::string, json_t, std::less<>>;
    using null_t = std::nullptr_t;
    using val_t = std::variant<null_t, double, std::string, bool, array_t, object_t>;
    val_t data{};


    json_t& operator[](std::integral auto&& index) { return std::get<array_t>(data)[index]; }

};

int main()
{

    int lvalue = 1;

    json_t f;
    f[1]; // WORKS
    f[lvalue]; // DOESN'T WORK
    f[std::move(lvalue)]; // DOES WORK
}

传入右值或移除operator[]参数的std::integral约束后,调用均可正常执行,原因如下:

  • 问题核心:std::integral auto&&不是万能引用。万能引用的成立要求是无额外类型约束的auto&&,或是模板参数的T&&形式(依赖模板参数推导)。当给auto&&加上std::integral约束后,编译器会将其解析为绑定右值的引用,而非支持引用折叠的万能引用。
  • 具体推导逻辑:
    • 传入右值1时,auto推导为int,std::integral<int>满足约束,参数类型为int&&,可以绑定右值,调用成功。
    • 传入左值lvalue时,auto仍推导为int,std::integral<int>虽满足约束,但int&&无法绑定左值,导致匹配失败。
    • 传入std::move(lvalue)时,实参转为右值,和第一种情况一致,调用成功。
  • 移除std::integral约束后,auto&&恢复为万能引用:编译器会根据实参的左/右值属性,通过引用折叠生成对应的左值或右值引用,自然能接受左值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 15:40:07