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

C++20中返回含unique_ptr引用的std::pair编译错误求助

问题:返回包含unique_ptr引用的std::pair编译失败

问题背景

使用C++20、GCC 11.1.0环境,尝试实现类方法返回由uint32_t和unique_ptr引用组成的std::pair,其中unique_ptr来自类内存储的unique_ptr向量,但编译报错。

编译错误信息

error: could not convert ‘std::make_pair(_T1&&, _T2&&) [with _T1 = unsigned int; _T2 = std::unique_ptr&; typename std::__strip_reference_wrapper<typename std::decay<_Tp2>::type>::__type = std::unique_ptr; typename std::decay<_Tp2>::type = std::decay<std::unique_ptr&>::type; typename std::__strip_reference_wrapper<typename std::decay<_Tp>::type>::__type = unsigned int; typename std::decay<_Tp>::type = unsigned int]((* &((Screen*)this)->Screen::panels.std::vector<std::unique_ptr >::emplace_back<>()))’ from ‘pair<[...],std::unique_ptr>’ to ‘pair<[...],std::unique_ptr&>’
67 | return std::make_pair<PanelID, Panel_Ptr&>(
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
| |
| pair<[...],std::unique_ptr>
68 | std::move(panelID), panels.emplace_back());
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

相关代码

class Screen
{
private:
    using PanelID = uint32_t;
    using Panel_Ptr = std::unique_ptr<Panel>;
    std::vector<Panel_Ptr> panels {};

public:
    std::pair<PanelID, Panel_Ptr&> foo()
    {
        PanelID panelID {static_cast<PanelID>(panels.size())};
        return std::make_pair<PanelID, Panel_Ptr&>(
            std::move(panelID), panels.emplace_back());
    }
};

解决方案

错误原因

std::make_pair内部会对模板参数做decay处理,即使你指定了引用类型,最终也会被剥离,返回的pair存储的是值类型而非引用,和你声明的返回类型std::pair<PanelID, Panel_Ptr&>不匹配。另外,unique_ptr不可拷贝,make_pair处理引用参数时会触发移动,最终生成的是包含unique_ptr值的pair,无法转换成带引用的pair。

修复代码

直接构造std::pair来精确控制成员类型,不要用std::make_pair:

std::pair<PanelID, Panel_Ptr&> foo()
{
    PanelID panelID {static_cast<PanelID>(panels.size())};
    auto& new_panel = panels.emplace_back();
    return {panelID, new_panel};
}

或者显式指定pair类型构造:

return std::pair<PanelID, Panel_Ptr&>(panelID, panels.emplace_back());

额外优化

std::move(panelID)是多余的——PanelID是基础类型,移动和拷贝性能完全一致,直接传递panelID即可。

注意事项

  • 返回的unique_ptr引用依赖Screen对象的生命周期,必须保证使用该引用时Screen对象仍有效,避免悬空引用。
  • 当需要精确控制pair成员的引用、const等修饰时,直接构造std::pair比std::make_pair更可靠,后者更适合自动推导简单类型的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:18:33