c++ - 仅移动结构在 MSVC 中的 std::map 中调用复制构造函数
问题描述
我有一个地图矢量。地图包含一个只能移动的结构。
当我尝试与此结构交互时,我在 MSVC 上遇到编译错误。
这是一个示例代码:
#include <map>
#include <memory>
#include <vector>
struct S {
std::unique_ptr<int> a;
};
int main() {
std::vector<std::map<float, S>> s;
s.emplace_back();
return 0;
}
我收到一条错误s.emplace_back()
消息:
C:/data/msvc/14.28.29333/include\xmemory(701): error C2280: 'std::pair<const float,S>::pair(const std::pair<const float,S> &)': attempting to reference a deleted function
C:/data/msvc/14.28.29333/include\utility(209): note: see declaration of 'std::pair<const float,S>::pair'
C:/data/msvc/14.28.29333/include\utility(209): note: 'std::pair<const float,S>::pair(const std::pair<const float,S> &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'S::S(const S &)'
<source>(7): note: 'S::S(const S &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::unique_ptr<int,std::default_delete<int>>::unique_ptr(const std::unique_ptr<int,std::default_delete<int>> &)'
C:/data/msvc/14.28.29333/include\memory(2686): note: 'std::unique_ptr<int,std::default_delete<int>>::unique_ptr(const std::unique_ptr<int,std::default_delete<int>> &)': function was explicitly deleted
C:/data/msvc/14.28.29333/include\xtree(358): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,_Ty&>(_Alloc &,_Objty *const ,_Ty &)' being compiled
with
[
_Alloc=std::allocator<std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<std::allocator<std::pair<const float,S>>>::void_pointer>>,
_Ty=std::pair<const float,S>,
_Objty=std::pair<const float,S>
]
C:/data/msvc/14.28.29333/include\xtree(358): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,_Ty&>(_Alloc &,_Objty *const ,_Ty &)' being compiled
with
[
_Alloc=std::allocator<std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<std::allocator<std::pair<const float,S>>>::void_pointer>>,
_Ty=std::pair<const float,S>,
_Objty=std::pair<const float,S>
]
C:/data/msvc/14.28.29333/include\xtree(2027): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer>::_Buynode<std::allocator<std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer>>,_Ty&>(std::allocator<std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer>> &,std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *,_Ty &)' being compiled
with
[
_Alloc=std::allocator<std::pair<const float,S>>,
_Ty=std::pair<const float,S>
]
C:/data/msvc/14.28.29333/include\xtree(2027): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer>::_Buynode<std::allocator<std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer>>,_Ty&>(std::allocator<std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer>> &,std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *,_Ty &)' being compiled
with
[
_Alloc=std::allocator<std::pair<const float,S>>,
_Ty=std::pair<const float,S>
]
C:/data/msvc/14.28.29333/include\xtree(1741): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Buynode<std::pair<const float,S>&>(std::pair<const float,S> &)' being compiled
with
[
_Alloc=std::allocator<std::pair<const float,S>>,
_Kty=float,
_Ty=S,
_Pr=std::less<float>
]
C:/data/msvc/14.28.29333/include\xtree(1741): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Buynode<std::pair<const float,S>&>(std::pair<const float,S> &)' being compiled
with
[
_Alloc=std::allocator<std::pair<const float,S>>,
_Kty=float,
_Ty=S,
_Pr=std::less<float>
]
C:/data/msvc/14.28.29333/include\xtree(1762): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_or_move<std::pair<const float,S>,std::integral_constant<bool,false>>(std::pair<const float,S> &,std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_tag,_Is_set)' being compiled
with
[
_Alloc=std::allocator<std::pair<const float,S>>,
_Kty=float,
_Ty=S,
_Pr=std::less<float>,
_Is_set=std::integral_constant<bool,false>
]
C:/data/msvc/14.28.29333/include\xtree(1762): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_or_move<std::pair<const float,S>,std::integral_constant<bool,false>>(std::pair<const float,S> &,std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_tag,_Is_set)' being compiled
with
[
_Alloc=std::allocator<std::pair<const float,S>>,
_Kty=float,
_Ty=S,
_Pr=std::less<float>,
_Is_set=std::integral_constant<bool,false>
]
C:/data/msvc/14.28.29333/include\xtree(1728): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_nodes<_Moveit>(std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *,std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *,_Moveit)' being compiled
with
[
_Alloc=std::allocator<std::pair<const float,S>>,
_Kty=float,
_Ty=S,
_Pr=std::less<float>,
_Moveit=std::_Tree<std::_Tmap_traits<float,S,std::less<float>,std::allocator<std::pair<const float,S>>,false>>::_Copy_tag
]
C:/data/msvc/14.28.29333/include\xtree(1728): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_nodes<_Moveit>(std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *,std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer> *,_Moveit)' being compiled
with
[
_Alloc=std::allocator<std::pair<const float,S>>,
_Kty=float,
_Ty=S,
_Pr=std::less<float>,
_Moveit=std::_Tree<std::_Tmap_traits<float,S,std::less<float>,std::allocator<std::pair<const float,S>>,false>>::_Copy_tag
]
C:/data/msvc/14.28.29333/include\xtree(902): note: see reference to function template instantiation 'void std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy<std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_tag>(const std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>> &,_Moveit)' being compiled
with
[
_Kty=float,
_Ty=S,
_Pr=std::less<float>,
_Alloc=std::allocator<std::pair<const float,S>>,
_Moveit=std::_Tree<std::_Tmap_traits<float,S,std::less<float>,std::allocator<std::pair<const float,S>>,false>>::_Copy_tag
]
C:/data/msvc/14.28.29333/include\xtree(902): note: see reference to function template instantiation 'void std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy<std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Copy_tag>(const std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>> &,_Moveit)' being compiled
with
[
_Kty=float,
_Ty=S,
_Pr=std::less<float>,
_Alloc=std::allocator<std::pair<const float,S>>,
_Moveit=std::_Tree<std::_Tmap_traits<float,S,std::less<float>,std::allocator<std::pair<const float,S>>,false>>::_Copy_tag
]
C:/data/msvc/14.28.29333/include\map(111): note: see reference to function template instantiation 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Tree<std::allocator<std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer>>>(const std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>> &,_Any_alloc &&)' being compiled
with
[
_Kty=float,
_Ty=S,
_Pr=std::less<float>,
_Alloc=std::allocator<std::pair<const float,S>>,
_Any_alloc=std::allocator<std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<std::allocator<std::pair<const float,S>>>::void_pointer>>
]
C:/data/msvc/14.28.29333/include\map(111): note: see reference to function template instantiation 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::_Tree<std::allocator<std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<_Alloc>::void_pointer>>>(const std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>> &,_Any_alloc &&)' being compiled
with
[
_Kty=float,
_Ty=S,
_Pr=std::less<float>,
_Alloc=std::allocator<std::pair<const float,S>>,
_Any_alloc=std::allocator<std::_Tree_node<std::pair<const float,S>,std::_Default_allocator_traits<std::allocator<std::pair<const float,S>>>::void_pointer>>
]
C:/data/msvc/14.28.29333/include\map(111): note: while compiling class template member function 'std::map<float,S,std::less<float>,std::allocator<std::pair<const float,S>>>::map(const std::map<float,S,std::less<float>,std::allocator<std::pair<const float,S>>> &)'
C:/data/msvc/14.28.29333/include\xmemory(701): note: see reference to function template instantiation 'std::map<float,S,std::less<float>,std::allocator<std::pair<const float,S>>>::map(const std::map<float,S,std::less<float>,std::allocator<std::pair<const float,S>>> &)' being compiled
C:/data/msvc/14.28.29333/include\vector(687): note: see reference to class template instantiation 'std::map<float,S,std::less<float>,std::allocator<std::pair<const float,S>>>' being compiled
C:/data/msvc/14.28.29333/include\vector(705): note: see reference to function template instantiation 'void std::vector<std::map<float,S,std::less<float>,std::allocator<std::pair<const float,S>>>,std::allocator<std::map<float,S,std::less<float>,std::allocator<std::pair<const float,S>>>>>::_Emplace_back_with_unused_capacity<>(void)' being compiled
<source>(12): note: see reference to function template instantiation 'void std::vector<std::map<float,S,std::less<float>,std::allocator<std::pair<const float,S>>>,std::allocator<std::map<float,S,std::less<float>,std::allocator<std::pair<const float,S>>>>>::emplace_back<>(void)' being compiled
Compiler returned: 2
您可以在此处查看 Godbolt 上的实际代码:https ://godbolt.org/z/qvMPYdc5q
它适用于 clang 和 GCC,但不适用于 MSVC(最新和 v19.28)。
我在某处看到 MSVC 要求 ctor & dtor 为 noexcept 以使地图使用移动构造函数,但即使在为S
结构定义 noexcept ctors & dtors 时,我也会遇到相同的错误。
MSVC 在做什么需要在这段代码中复制?我怎样才能在这里强制移动?
解决方案
推荐阅读
- php - 创建另一个控制器和模型不适用于 codeigniter
- mysql - 通过两个表连接查询 Flask-SQLAlchemy - 连接不起作用
- c++ - OpenCV C++ 缩放功能
- ruby-on-rails - 在哪里存储 Rails 中长类名的缩写?
- c++ - clang-format 显示将哪种样式选项应用于代码
- scala - 如何将一些捆绑包作为模块参数传递?
- jquery - 在 Ajax 内部使 Ajax 循环
- python - 没有名为“scipy.sparse._sparsetools”的模块
- excel - 如何使用java在excel中打开管道分隔的csv文件
- reactjs - React Custom Hook 产生警告:超过最大更新深度