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

编译器差异:const成员函数内mutable lambda值捕获*this时this的类型

#include <type_traits>

struct S {
  void f() const {
    (void)[*this]() mutable {
      static_assert(
          std::is_same_v<decltype(this), S *>);  // GCC与MSVC下编译失败
      static_assert(
          std::is_same_v<decltype(this), const S *>);  // Clang下编译失败
      (void)this;
    }
    ();
  }
};

int main() {}

结论

Clang的实现符合现行C++标准规定,GCC与MSVC的行为属于尚未跟进标准缺陷修复的偏差。

规则依据与推导过程

  1. 基础背景
  • 代码中S::f是const限定成员函数,函数内的原始this指针类型为const S*,解引用得到的*this是const S&类型。
  • [*this]是C++17引入的按值捕获语法,语义是将当前*this对象拷贝一份,作为lambda闭包类型的非静态数据成员。
  1. 核心规则的标准修正
    早期C17标准没有明确[*this]捕获场景下lambda体内this的解析规则,存在表述漏洞,后续C标准委员会核心工作组通过CWG Issue 2305完成了规则补全,明确规定:

当lambda使用[*this]按值捕获当前类实例时,lambda体内所有对this的引用,都会被解析为指向捕获得到的实例副本的指针,而非外层成员函数的原始this指针。

  1. 结合本例推导
  • 按值拷贝会剥离源对象的顶层const限定,因此捕获得到的副本本身是无cv限定的S类型。
  • 本例中lambda添加了mutable修饰符,意味着lambda的operator()成员函数是无const限定的,访问闭包成员时不会附加const约束。
  • 因此指向副本的this指针类型为S*,与Clang的判定完全一致。
  1. GCC、MSVC行为的成因
    这两款编译器目前尚未完整实现CWG 2305的决议,仍然将lambda体内的this错误解析为外层const成员函数的原始const S*指针,不符合现行C++标准的要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 07:39:04