【问题标题】:MSVC error C2280 (attempting to reference a deleted function) that works with all other compilers适用于所有其他编译器的 MSVC 错误 C2280(试图引用已删除的函数)
【发布时间】:2020-10-13 17:24:46
【问题描述】:

以下代码无法使用所有最新版本的 MSVC 编译,但可以编译所有最新版本的 GCC 和 Clang:

#include <vector>
#include <memory>
#include <list>

using namespace std;

struct A
{
    int a;
};

int main (int argc, char **argv)
{
  vector<list<unique_ptr<A>>> v;
  v.emplace_back();
}

对于所有最新版本的 MSVC,emplace_back() 调用会触发编译器错误 C2280“试图引用已删除的函数”。

这段代码真的有错误吗?我理解它是在向量 v 的末尾就地构造一个空列表。

如果它错误,我应该如何构造这个列表并将它放在向量中?我已经尝试过显式构造一个空列表并将其移动到向量中,结果与 C2280 相同:

list<unique_ptr<A>> elem;
v.push_back(move(elem));

【问题讨论】:

  • 编译成什么标准?
  • c++17,例如gcc.godbolt.org/z/5E6qzc
  • 错误似乎仍在制作副本。 emplace_back() 不应该复制,但我不知道实际的标准措辞。

标签: c++ visual-c++


【解决方案1】:

看起来这是一个更普遍的问题示例,MSVC 标准库的主要实现者在this r/cpp thread 中已确认该问题。该问题适用于所有container&lt;container&lt;unique_ptr&gt;&gt; 构造,其中内部容器是基于节点的容器(如listmap)。他提出了一个不愉快的解决方法:

但是,您的代码有一个可能的解决方法。如果你包装 你内心的container&lt;unique_ptr&lt;whatever&gt;&gt; 在一个手动的类中 删除它的副本并默认它的移动(基本上告诉 编译器标准应该做什么,但没有),然后 vector&lt;YourWrapper&lt;container&lt;unique_ptr&lt;whatever&gt;&gt;&gt;&gt; 会表现 正确(并且您将在重新分配期间获得移动)。

就我自己而言,我很不情愿地将unique_ptr 替换为shared_ptr。它不在性能关键代码中,所以我愿意接受技术上不必要的性能损失。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 2014-02-19
    • 2014-09-15
    • 2015-09-24
    • 2021-11-13
    • 1970-01-01
    • 2020-08-21
    相关资源
    最近更新 更多