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

关于右值引用作为类成员的C++技术疑问

C++右值引用结构体相关问题

代码示例

#include <iostream>

template<typename T>
struct test
{
    T &&val;
};


long double get() { return 6; }
long double &get_ref()
{
    static long double a = 5;
    return a;
}

int main()
{
    test<long double> t_by_value{get()};       // 我认为这是容器
    test<long double&> t_by_ref{get_ref()};    // 我认为这是视图
    std::cout << t_by_value.val << " " << t_by_ref.val << "\n";
    // 输出:6 5
    std::cout << sizeof(t_by_value) << " " << sizeof(t_by_ref) << "\n";
    // 32位系统下输出:4 4
}

问题

  1. 上述代码是否正确,是否存在未定义行为?
  2. 若代码正确,test<long double>中的long double存储在哪里,因为它并未包含在对象中?
  3. 我将test<long double>称为容器、test<long double&>称为视图的说法是否正确?

回答

  1. 代码正确,不存在未定义行为。test<long double>中的val是右值引用,当它绑定到get()返回的临时long double对象时,C++标准明确规定:绑定到右值引用的临时对象,其生命周期会被延长至该引用的生命周期结束,也就是t_by_value对象销毁时。因此访问t_by_value.val是完全安全的。

  2. test<long double>的结构体内部只存储了右值引用(大小等同于指针),真正的long double临时对象被存储在栈内存中(或编译器优化后的其他内存区域),并没有嵌入到test结构体对象里。临时对象的生命周期被右值引用延长,只要t_by_value存在,这个临时对象就不会被销毁。

  3. 该说法并不准确:

    • test<long double>不能称为容器。容器的核心特性是管理数据的存储与生命周期,而这个结构体只是持有一个右值引用,没有真正“容纳”long double对象,临时对象的生命周期是靠C++标准规则被动延长的,并非结构体主动管理。
    • test<long double&>可以勉强看作一种极简视图,因为它持有对已存在对象的引用,本身不拥有数据,仅提供访问途径,符合视图“不持有数据、仅引用数据”的基本特征,但它是非常简陋的实现,和标准库中的视图(如std::span)的功能不可同日而语。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:23:03