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

时间:2018-07-11 22:54:35

标签: c++ c++11 shared-ptr stdvector

我正在尝试使用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 studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\xutility(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 studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\system_error(284): note: could be 'bool std::operator ==(const std::error_condition &,const std::error_condition &) noexcept'
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\system_error(278): note: or       'bool std::operator ==(const std::error_condition &,const std::error_code &) noexcept'
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\system_error(272): note: or       'bool std::operator ==(const std::error_code &,const std::error_condition &) noexcept'
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\system_error(266): note: or       'bool std::operator ==(const std::error_code &,const std::error_code &) noexcept'
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\exception(330): note: or       'bool std::operator ==(const std::exception_ptr &,std::nullptr_t) noexcept'
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\exception(325): note: or       'bool std::operator ==(std::nullptr_t,const std::exception_ptr &) noexcept'
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\exception(320): note: or       'bool std::operator ==(const std::exception_ptr &,const std::exception_ptr &) noexcept'
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\memory(1615): note: or       'bool std::operator ==<Missile>(const std::shared_ptr<Missile> &,std::nullptr_t) noexcept'
1>c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\xutility(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 studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\xutility(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 studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\xutility(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 studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\xutility(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 studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\xutility(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 studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\xutility(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 studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\xutility(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:\users\thàng long\documents\visual studio 2017\projects\asteroid\asteroid\src\game.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>        ]

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

1 个答案:

答案 0 :(得分:3)

您正在使用一元谓词调用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(); });

编辑:以上解决方案可让您删除可以删除的 first 导弹。如果要删除个可以删除的导弹,则可以使用std::remove_if。它的用法带有一个令人困惑的成语,但我将尽力解释。 std::remove_if也需要两个迭代器和一个一元谓词,但实际上并没有 remove 元素(因为这样做,它需要知道仅给定迭代器的容器,即impossible)。相反,如果应该删除元素,它将 shuffle 元素拖到容器的后面,并向这些元素中的第一个返回新的迭代器。结合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()
);