编译错误 std::vector<std::shared_ptr<T>>迭代器和擦除方法

Compiling errors std::vector<std::shared_ptr<T>> iterator and erase methods

本文关键字:gt std lt 擦除 迭代器 方法 shared 错误 vector 编译 ptr      更新时间:2023-10-16

我正在尝试用C++和SFML制作一个游戏。但是,我对Missile类有一些问题。我有一个std::vector<std::shared_ptr<Missile>>,我想做的是在导弹超出射程时将其移除。

我对StackOverflow做了一些研究,发现了这样的东西:

auto list = ship->getMissilesToDisplay(); // returns the std::vector<std::shared_ptr<Missile>>
auto iterator = std::find(list.begin(), list.end(), [](const std::shared_ptr<Missile>& m) { return m->canDelete(); });
list.erase(iterator);

但当我编译这个时,我会遇到一些错误:

1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includexutility(3579): error C2678: binary '==': no operator found which takes a left-hand operand of type 'std::shared_ptr<Missile>' (or there is no acceptable conversion)
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includesystem_error(284): note: could be 'bool std::operator ==(const std::error_condition &,const std::error_condition &) noexcept'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includesystem_error(278): note: or       'bool std::operator ==(const std::error_condition &,const std::error_code &) noexcept'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includesystem_error(272): note: or       'bool std::operator ==(const std::error_code &,const std::error_condition &) noexcept'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includesystem_error(266): note: or       'bool std::operator ==(const std::error_code &,const std::error_code &) noexcept'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includeexception(330): note: or       'bool std::operator ==(const std::exception_ptr &,std::nullptr_t) noexcept'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includeexception(325): note: or       'bool std::operator ==(std::nullptr_t,const std::exception_ptr &) noexcept'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includeexception(320): note: or       'bool std::operator ==(const std::exception_ptr &,const std::exception_ptr &) noexcept'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includememory(1615): note: or       'bool std::operator ==<Missile>(const std::shared_ptr<Missile> &,std::nullptr_t) noexcept'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includexutility(3579): note: or       'built-in C++ operator==(bool (__cdecl *)(const std::shared_ptr<Missile> &), bool (__cdecl *)(const std::shared_ptr<Missile> &))'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includexutility(3579): note: or       'built-in C++ operator==(bool (__stdcall *)(const std::shared_ptr<Missile> &), bool (__stdcall *)(const std::shared_ptr<Missile> &))'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includexutility(3579): note: or       'built-in C++ operator==(bool (__fastcall *)(const std::shared_ptr<Missile> &), bool (__fastcall *)(const std::shared_ptr<Missile> &))'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includexutility(3579): note: or       'built-in C++ operator==(bool (__vectorcall *)(const std::shared_ptr<Missile> &), bool (__vectorcall *)(const std::shared_ptr<Missile> &))'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includexutility(3579): note: while trying to match the argument list '(std::shared_ptr<Missile>, const Game::clean::<lambda_42809c80e7e2bc392c11a08cf362033b>)'
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includexutility(3592): note: see reference to function template instantiation '_InIt std::_Find_unchecked1<_InIt,_Ty>(_InIt,const _InIt,const _Ty &,std::false_type)' being compiled
1>        with
1>        [
1>            _InIt=std::shared_ptr<Missile> *,
1>            _Ty=Game::clean::<lambda_42809c80e7e2bc392c11a08cf362033b>
1>        ]
1>c:program files (x86)microsoft visual studio2017enterprisevctoolsmsvc14.14.26428includexutility(3601): note: see reference to function template instantiation '_InIt std::_Find_unchecked<std::shared_ptr<Missile>*,_Ty>(const _InIt,const _InIt,const _Ty &)' being compiled
1>        with
1>        [
1>            _InIt=std::shared_ptr<Missile> *,
1>            _Ty=Game::clean::<lambda_42809c80e7e2bc392c11a08cf362033b>
1>        ]
1>c:usersthàng longdocumentsvisual studio 2017projectsasteroidasteroidsrcgame.cpp(13): note: see reference to function template instantiation '_InIt std::find<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>,Game::clean::<lambda_42809c80e7e2bc392c11a08cf362033b>>(_InIt,const _InIt,const Game::clean::<lambda_42809c80e7e2bc392c11a08cf362033b> &)' being compiled
1>        with
1>        [
1>            _InIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::shared_ptr<Missile>>>>,
1>            _Ty=std::shared_ptr<Missile>
1>        ]

也许我误解了如何实现这段代码?

您使用一元谓词调用std::find,但std::find需要一个值类型来测试那里的相等性。因此,您尝试将std::shared_ptr<Missile>与lambda进行比较,这当然是不可能的,并且会导致典型的可怕的模板错误消息。您可能想要使用std::find_if,它接受一个谓词:

std::find_if(list.begin(), list.end(), [](const std::shared_ptr<Missile>& m) { return m->canDelete(); });

编辑:以上解决方案将允许您删除可以删除的第一个导弹。如果您想删除每个可以删除的导弹,可以使用std::remove_if。它的用法带有一个令人困惑的习语,但我会尽力解释一下。std::remove_if还接受两个迭代器和一个一元谓词,但它实际上并没有删除元素(因为要做到这一点,它需要知道只给定迭代器的容器,这是不可能的(。相反,如果元素应该被删除,它会将它们拖到容器的后面,并向这些元素中的第一个返回一个新的迭代器。这与std::vector::erase(iterator first, iterator last);耦合以删除那些尾随元素。现在对于实际的代码,使用缩进来帮助分离移动部件:

list.erase(
std::remove_if(
list.begin(),
list.end(),
[](const std::shared_ptr<Missile>& m){ m->canDelete(); }
),
list.end()
);