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

关于C++引用折叠规则的疑问及&&+&&→&&场景示例请求

C++引用折叠规则验证与场景示例

代码理解验证

针对你的实验代码,逐个分析调用的实际等价情况:

  1. func(a);
    你的理解错误。a是左值,根据通用引用的模板参数推导规则,当T&&绑定左值时,T会被推导为左值引用类型(即int&),因此实际调用的是func<int&>(a)。此时参数t的类型为int& &&,经过引用折叠后最终变为int&。

  2. func(10);
    10是右值,通用引用绑定右值时,T推导为非引用类型int,实际调用func<int>(10),参数t的类型为int&&,无引用折叠发生。

  3. func(std::move(a));
    std::move(a)将左值转换为右值引用(本质仍属于右值范畴),因此T推导为int,实际调用func<int>(std::move(a)),参数t的类型为int&&。

  4. func(b1);
    你的理解正确。b1是int&类型的左值,T推导为int&,调用func<int&>(b1),参数t的类型int& &&经过引用折叠变为int&,符合& + && → &的规则。

  5. func(b2);
    你的理解错误。注意:所有命名的引用都是左值——哪怕b2是int&&类型,它作为命名变量仍属于左值。因此传递b2时,通用引用绑定左值,T推导为int&,实际调用func<int&>(b2),参数t的类型int& &&折叠为int&,同样符合& + && → &的规则。

&& + && → &&引用折叠场景示例

这类折叠发生在T被推导为右值引用类型,或显式指定T为右值引用时,结合通用引用的&&触发折叠:

场景1:显式指定模板参数为右值引用

template<typename T>
void func(T&& t) {}

int main() {
    int a = 10;
    // 显式指定T为int&&,此时T&&即int&& &&,折叠为int&&
    func<int&&>(std::move(a));
}

场景2:嵌套模板推导中的右值引用传递

template<typename T>
void inner_func(T&& t) {}

template<typename T>
void outer_func(T&& t) {
    // 当outer_func的T被推导为int&&时,传递给inner_func的T&&即int&& &&,折叠为int&&
    inner_func(std::forward<T>(t));
}

int main() {
    int a = 10;
    outer_func(std::move(a));
}

场景3:typedef/别名中的右值引用折叠

using IntRRef = int&&;

template<typename T>
void func(T&& t) {}

int main() {
    int a = 10;
    // T指定为IntRRef(即int&&),T&&即int&& &&,折叠为int&&
    func<IntRRef>(std::move(a));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 19:01:09