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

为何将右值绑定到const类型会使其成为左值?

问题:const修饰std::pair成员类型导致函数重载匹配差异

我这段代码运行后输出“lvalue”,但如果移除MyPair第一个类型的const修饰,会得到预期的“rvalue”。想了解const在此处起到了什么作用?

#include <iostream>
#include <utility>
#include <string>

using MyPair = std::pair<const std::string, int>;

void func(std::string&& str)
{
    std::cout << "rvalue" << std::endl;
}

void func(const std::string& str)
{
    std::cout << "lvalue" << std::endl;
}

template<typename T>
void func_forward(T&& p)
{
    func(std::forward<T>(p).first);
}

void test(MyPair&& p)
{
    func_forward(std::move(p));
}

int main()
{
    test({"hello", 3});
    return 0;
}

问题解析

核心原因是C++中右值对象的成员访问值类别规则,const修饰直接改变了成员访问表达式的性质:

  1. 带const修饰的情况:

    • func_forward里std::forward<T>(p)返回的是MyPair&&类型的右值对象
    • 访问该右值的first成员时,由于first的类型是const std::string,C++规定右值对象的const限定成员访问结果是左值
    • 这个左值会匹配func(const std::string&)重载,因此输出"lvalue"
  2. 移除const修饰的情况:

    • 同样std::forward<T>(p)返回MyPair&&右值对象
    • 此时first是std::string(非const),C++规定右值对象的非const成员访问结果是xvalue(属于右值范畴)
    • 这个右值会匹配func(std::string&&)重载,因此输出"rvalue"

关键规则总结

对右值对象的非静态数据成员访问:

  • 非const成员:访问结果为xvalue(可移动右值),能绑定到右值引用
  • const成员:访问结果为左值,只能绑定到const左值引用(因为const成员不可修改,编译器将其视为左值以保证安全)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:28:34