微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

仅移动结构在 MSVC 中的 std::map 中调用复制构造函数

如何解决仅移动结构在 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> &)': 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>> &)': 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,_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,S>
        ]
C:/data/msvc/14.28.29333/include\xtree(2027): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree_node<std::pair<const float,std::_Default_allocator_traits<_Alloc>::void_pointer>::_Buynode<std::allocator<std::_Tree_node<std::pair<const float,std::_Default_allocator_traits<_Alloc>::void_pointer>>,_Ty&>(std::allocator<std::_Tree_node<std::pair<const float,std::_Default_allocator_traits<_Alloc>::void_pointer>> &,std::_Tree_node<std::pair<const float,std::_Default_allocator_traits<_Alloc>::void_pointer> *,_Ty &)' being compiled
        with
        [
            _Alloc=std::allocator<std::pair<const float,S>>,S>
        ]
C:/data/msvc/14.28.29333/include\xtree(1741): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,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,_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,_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,false>>::_copy_or_move<std::pair<const float,std::integral_constant<bool,false>>(std::pair<const float,S> &,std::_Tree<std::_Tmap_traits<_Kty,false>>::_copy_tag,_Is_set)' being compiled
        with
        [
            _Alloc=std::allocator<std::pair<const float,_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,false>
        ]
C:/data/msvc/14.28.29333/include\xtree(1728): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const float,false>>::_copy_nodes<_Moveit>(std::_Tree_node<std::pair<const float,_Moveit)' being compiled
        with
        [
            _Alloc=std::allocator<std::pair<const float,_Moveit=std::_Tree<std::_Tmap_traits<float,S,std::less<float>,std::allocator<std::pair<const float,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,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,false>>::_copy<std::_Tree<std::_Tmap_traits<_Kty,false>>::_copy_tag>(const std::_Tree<std::_Tmap_traits<_Kty,false>> &,_Moveit)' being compiled
        with
        [
            _Kty=float,_Alloc=std::allocator<std::pair<const float,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,false>>::_Tree<std::allocator<std::_Tree_node<std::pair<const float,std::_Default_allocator_traits<_Alloc>::void_pointer>>>(const std::_Tree<std::_Tmap_traits<_Kty,_Any_alloc &&)' being compiled
        with
        [
            _Kty=float,_Any_alloc=std::allocator<std::_Tree_node<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,S>>>::void_pointer>>
        ]
C:/data/msvc/14.28.29333/include\map(111): note: while compiling class template member function 'std::map<float,S>>>::map(const std::map<float,S>>> &)'
C:/data/msvc/14.28.29333/include\xmemory(701): note: see reference to function template instantiation 'std::map<float,S>>> &)' being compiled
C:/data/msvc/14.28.29333/include\vector(687): note: see reference to class template instantiation 'std::map<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::allocator<std::map<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>>>>>::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 在做什么需要这段代码的副本?我怎样才能强制移动到这里?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。