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

为何const成员函数返回非const引用?C++类型推导疑问

C++成员函数返回值常量性疑问解答

先明确核心规则:在const成员函数中,this指针的类型是const 类名*,对成员的访问会受到const限定,但引用类型的成员和普通成员的处理逻辑不同——C++中不存在“const引用”(引用本身不可修改,加const无意义),所以const限定不会把int&类型的成员转为const int&,只会把引用变量本身视为不可修改(但这对引用的目标类型无影响)。

问题1:GetAutoRef与GetAutoRefJ的返回值常量性为何不同?

  • GetAutoRef()是const成员函数,访问成员i时,i的类型会被限定为const int。返回值声明为auto&,auto会推导为const int,最终返回const int&,符合预期。
  • GetAutoRefJ()同样是const成员函数,但访问的成员j是int&类型。如核心规则所述,const限定不会改变引用的目标类型,j在函数内仍为int&。返回值auto&中的auto推导为int,最终返回int&,不带const属性。

问题2:GetDecltypeAutoJ的返回值为何不具备const属性?通过const this访问成员j时,j难道不应是const的吗?

  • 首先,const成员函数中访问j时,j的类型不会变成const int&。因为j本身是引用类型,const限定只能作用于引用变量本身(而引用本身不可修改,这个限定无意义),不会传递到引用的目标对象上,所以j在函数内依然是int&。
  • decltype(auto)会严格按照表达式的类型推导返回值:return j的表达式类型是int&,因此返回值就是int&,不带const属性。
  • 补充对比:GetDecltypeAuto()中return i,i在const函数内是const int,但这里是值返回(拷贝i的值),所以decltype(auto)推导为int,和GetAuto()的返回类型一致。

附原测试代码

#include <type_traits>

struct A {
    int i;
    int& j = i;

    decltype(auto) GetDecltypeAuto() const { return i; }
    auto           GetAuto        () const { return i; }
    auto&          GetAutoRef     () const { return i; }

    decltype(auto) GetDecltypeAutoJ() const { return j; }
    auto           GetAutoJ        () const { return j; }
    auto&          GetAutoRefJ     () const { return j; }
};

int main() {
 A a{5};
 static_assert(std::is_same_v<decltype(a.GetDecltypeAuto()), int>       );
 static_assert(std::is_same_v<decltype(a.GetAuto()        ), int>       );
 static_assert(std::is_same_v<decltype(a.GetAutoRef()), const int&>); //as expected

 static_assert(std::is_same_v<decltype(a.GetDecltypeAutoJ()), int&>); // no const?
 static_assert(std::is_same_v<decltype(a.GetAutoJ()        ), int> );
 static_assert(std::is_same_v<decltype(a.GetAutoRefJ()     ), int&>); // no const?
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:51:56