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

std::reference_wrapper的常量正确性是否违反C++23标准规则?

关于const限定的std::reference_wrapper是否违反C++23 [res.on.data.races]#3条款的疑问

const限定的std::reference_wrapper<T>行为类似引用或者T* const,示例代码如下:

#include <functional>

struct S {
    void operator()() { i++; }
    int i = 0;
};

int main() {
    S s;
    const std::reference_wrapper<S> r = s;
    // 此时 s.i == 0
    r();
    // 此时 s.i == 1

    S* const p = &s;
    // 此时 s.i == 1
    (*p)();
    // 此时 s.i == 2
}

变量r是const的,且std::reference_wrapper::operator()是const成员函数,因此可以调用它,而这会修改被指向的对象。但该operator()是标准库函数,因此C++23标准中的[res.on.data.races]#3条款适用于它:

C++标准库函数不得直接或间接修改当前线程以外的线程可访问的对象(见[intro.multithread]),除非这些对象是通过函数的非const参数(包括this)直接或间接访问的。

请问std::reference_wrapper是否违反了该规则?


回答

没有违反该规则,原因如下:

  • std::reference_wrapper的设计目标是作为引用的可复制包装器,它的const成员函数(比如operator())本质是通过内部持有的引用代理操作被包装的对象。这里被修改的并非const std::reference_wrapper自身,而是它绑定的外部对象S。
  • [res.on.data.races]#3条款的核心约束是:禁止标准库函数在未通过非const参数(包括this)授权的情况下,修改跨线程可访问的外部对象。而在这个场景中,用户通过std::reference_wrapper调用operator(),本质是明确要求修改自己提供的被引用对象,标准库只是执行了用户的意图,并非擅自修改外部状态。
  • 从语义上看,const std::reference_wrapper<S>等价于const S&(引用本身不可重绑定,但可修改非const的被引用对象)或S* const(指针本身不可改指向,但可解引用修改对象),这种行为完全符合C++中引用和指针的既定语义,标准库的实现只是遵循了这一语义,并未违反条款。

内容的提问来源于stack exchange,提问作者Dr. Gut

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 07:00:09