为啥在将唯一指针插入无序映射时 C++ 会给我一个错误?

Posted

技术标签:

【中文标题】为啥在将唯一指针插入无序映射时 C++ 会给我一个错误?【英文标题】:why does C++ give me an error when inserting unique pointer into unordered map?为什么在将唯一指针插入无序映射时 C++ 会给我一个错误? 【发布时间】:2020-12-30 23:01:02 【问题描述】:

在具有以下成员和方法的类中:

    std::unordered_map<std::string, std::unique_ptr<test::Test>> m_Tests;
    
    void test::TestMenu::addTest(const std::string &testName, std::unique_ptr<test::Test> test) 
        m_Tests.emplace(testName, test);
    

这样称呼:

testMenu.addTest("Test Clear Color", std::make_unique<test::TestClearColor>());

编译器传递错误:

error: no matching function for call to 'construct_at'
          std::construct_at(__p, std::forward<_Args>(__args)...);

我的问题是为什么 C++ 会给我这个错误?

【问题讨论】:

【参考方案1】:

这个:

m_Tests.emplace(testName, test);

将尝试复制test,因为 (a) 它是一个 lvalue 表达式,(b) 表达式永远没有引用类型,并且 (c) emplace 不采用左值引用.

unique_ptrs 无法复制。

这就是std::move 的用途!

m_Tests.emplace(testName, std::move(test));

现在您有了一个右值表达式,它非常适合绑定到emplace 确实采用的右值引用。

我实际上稍微有点说谎,而且事情有点复杂,因为emplace 是可变参数。但是无所谓。重要的是,您正在为此 unique_ptr 创建所有权链中的另一个链接,最终将所有权传递给地图,而 std::move 就是这样做的方法。

【讨论】:

以上是关于为啥在将唯一指针插入无序映射时 C++ 会给我一个错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这会给我一个 Java 中的 ClassCastException,而它在 C++ 中运行良好?

在 C++ 中使用指向我的数组的指针会给我一个“未处理的异常”吗?

在无序映射中插入智能指针调用析构函数

C++ 使用具有无序映射的模板类型

为啥在我制作折线图时,plotly express 会给我一个属性错误?

为啥当我知道有足够的内存空间时 cudaMalloc 会给我一个错误?