C++ 如何从项目向量中按名称删除项目成员?

C++ 如何从项目向量中按名称删除项目成员?,c++,vector,struct,find,C++,Vector,Struct,Find,我想通过使用find和迭代器搜索项目名称来删除项目,但该项目不起作用?我尝试了许多不同的方法,我的控制台只是显示了很多错误 这是我的密码: struct Item { struct Item { string name; float price; unsigned int quantity; }; Item i1 = {"Item 2", 0.05, 3}; Item i2 = {"Item 1", 0.10, 1}; Item i3 =

我想通过使用
find
和迭代器搜索项目名称来删除
项目
,但该项目不起作用?我尝试了许多不同的方法,我的控制台只是显示了很多错误

这是我的密码:

struct Item {
  struct Item {
  string name;
  float price;
  unsigned int quantity;
};

Item i1 = {"Item 2", 0.05, 3};
Item i2 = {"Item 1", 0.10, 1};
Item i3 = {"Item 3", 0.25, 2};
  
vector <Item> inventory;
我不知道我是否没有得到正确的值,或者我需要找到值(名称)的索引

以下是错误:

In file included from inventory.cpp:1:
In file included from ./inventory.h:7:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/algorithm:61:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algobase.h:71:
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/predefined_ops.h:241:17: error: invalid operands to binary expression
      ('Item' and 'const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >')
        { return *__it == _M_value; }
                 ~~~~~ ^  ~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algo.h:869:7: note: in instantiation of function template
      specialization '__gnu_cxx::__ops::_Iter_equals_val<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>
      > >::operator()<__gnu_cxx::__normal_iterator<Item *, std::vector<Item, std::allocator<Item> > > >' requested here
        if (!__pred(__first))
             ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algo.h:906:19: note: in instantiation of function template
      specialization 'std::__remove_if<__gnu_cxx::__normal_iterator<Item *, std::vector<Item, std::allocator<Item> > >,
      __gnu_cxx::__ops::_Iter_equals_val<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >' requested
      here
      return std::__remove_if(__first, __last,
                  ^
inventory.cpp:56:23: note: in instantiation of function template specialization 'std::remove<__gnu_cxx::__normal_iterator<Item *,
      std::vector<Item, std::allocator<Item> > >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >'
      requested here
      inventory.erase(remove(inventory.begin(), inventory.end(), name), inventory.end());
                      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/system_error:292:3: note: candidate function not viable: no known conversion
      from 'Item' to 'const std::error_code' for 1st argument
  operator==(const error_code& __lhs, const error_code& __rhs) noexcept
  ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/system_error:297:3: note: candidate function not viable: no known conversion
      from 'Item' to 'const std::error_code' for 1st argument
  operator==(const error_code& __lhs, const error_condition& __rhs) noexcept
在清单中包含的文件中。cpp:1:
在包含于./inventory.h:7的文件中:
在/usr/bin/./lib/gcc/x86_64-linux-gnu/8/../../../../../../../include/c++/8/算法中包含的文件中:61:
在/usr/bin/./lib/gcc/x86_64-linux-gnu/8/../../../../../../../include/c++/8/bits/stl_algobase.h:71中包含的文件中:
/usr/bin/./lib/gcc/x86_64-linux-gnu/8/../../../../../../../include/c++/8/bits/prefined_ops.h:241:17:错误:二进制表达式的操作数无效
('Item'和'const std:uu cxx11::basic_string')
{return*\uu it==\u M_value;}
~~~~~ ^  ~~~~~~~~
/usr/bin/./lib/gcc/x86_64-linux-gnu/8/../../../../../../../include/c++/8/bits/stl_algo.h:869:7:注意:在函数模板的实例化中
此处请求的专用化“\uu gnu\u cxx::\uu ops::\u Iter\u equals\u val::operator()”
如果(!\uuuu pred(\uuuu first))
^
/usr/bin/./lib/gcc/x86_64-linux-gnu/8/../../../../../../../../include/c++/8/bits/stl_algo.h:906:19:注意:在函数模板的实例化中
特殊化'std::\如果请求,请删除
在这里
返回标准::\uuuuu删除\uu如果(\uuuuu首先,\uuuuu最后,
^
inventory.cpp:56:23:注意:在函数模板专门化的实例化中'std::remove'
在此请求
inventory.erase(删除(inventory.begin()、inventory.end()、name)、inventory.end());
^
/usr/bin/./lib/gcc/x86_64-linux-gnu/8/../../../../../../../include/c++/8/system_错误:292:3:注意:候选函数不可行:无已知转换
第一个参数从“Item”到“const std::error_code”
运算符==(常量错误代码和常量错误代码和常量错误代码)无例外
^
/usr/bin/./lib/gcc/x86_64-linux-gnu/8/../../../../../../../include/c++/8/system_错误:297:3:注意:候选函数不可行:无已知转换
第一个参数从“Item”到“const std::error_code”
运算符==(常量错误代码和常量错误条件和常量错误rhs)无异常
您需要一个只匹配名称的函数:

  auto newEnd = std::remove_if(inventory.begin(), 
                               inventory.end(), 
                               [&name](const auto& item){return item.name == name;});
  inventory.erase(newEnd, inventory.end());
我将
remove\u if
移动到分隔行以使其更可读。

您需要一个只匹配名称的函数:

  auto newEnd = std::remove_if(inventory.begin(), 
                               inventory.end(), 
                               [&name](const auto& item){return item.name == name;});
  inventory.erase(newEnd, inventory.end());

我将
remove\u if
移动到分隔行以使其更可读。

问题在于这行

inventory.erase(remove(inventory.begin(), inventory.end(), name), inventory.end());
库存
似乎是
项目
的容器。但您无法将
项目
的对象与
标准::字符串
名称
)进行比较。 如果只有一项需要删除,可以使用lambda使用
find\u If
解决此问题

bool Inventory::removeItem(string const& name) {
   if(hasItem(name)) {
      inventory.erase(
         std::find_if(cbegin(inventory), cend(inventory),
            [&name](Item const& item){ return item.name == name; }));      
      return true;
   }
   return false;
}
注意,我将函数签名更改为使用常量字符串引用,以防止不必要的复制。在lambda中,您还可以通过引用捕获

在C++20中,这一切都将简化,您可以使用:

p、 美国。
hasValue
可以使用该算法实现

bool Inventory::hasItem(string const& name) const {
   return std::any_of(cbegin(inventory), cend(inventory),
      [&name](Item const& item){ return item.name == name });
}
在C++20中,甚至可以使用以下范围编写:

bool Inventory::hasItem(string const& name) const {
   return std::ranges::any_of(inventory, // input container
      [&name](string const& itemName){ return itemName == name }, // predicate
      &Item::name); // projection
}

问题在于这条线

inventory.erase(remove(inventory.begin(), inventory.end(), name), inventory.end());
库存
似乎是
项目
的容器。但您无法将
项目
的对象与
标准::字符串
名称
)进行比较。 如果只有一项需要删除,可以使用lambda使用
find\u If
解决此问题

bool Inventory::removeItem(string const& name) {
   if(hasItem(name)) {
      inventory.erase(
         std::find_if(cbegin(inventory), cend(inventory),
            [&name](Item const& item){ return item.name == name; }));      
      return true;
   }
   return false;
}
注意,我将函数签名更改为使用常量字符串引用,以防止不必要的复制。在lambda中,您还可以通过引用捕获

在C++20中,这一切都将简化,您可以使用:

p、 美国。
hasValue
可以使用该算法实现

bool Inventory::hasItem(string const& name) const {
   return std::any_of(cbegin(inventory), cend(inventory),
      [&name](Item const& item){ return item.name == name });
}
在C++20中,甚至可以使用以下范围编写:

bool Inventory::hasItem(string const& name) const {
   return std::ranges::any_of(inventory, // input container
      [&name](string const& itemName){ return itemName == name }, // predicate
      &Item::name); // projection
}

在c++20中,如果要根据成员的值删除范围中的所有元素,可以编写以下代码:

auto [begin, end] = std::ranges::remove(inventory, name, &Item::name);     
inventory.erase(begin, end);    
这是一个例子

如果只想删除第一项,可以编写:

inventory.erase(std::ranges::find(inventory, name, &Item::name));     
在这种情况下,您需要确保该项存在于该范围内,您可以通过与该范围的
end
进行比较来实现这一点


下面是c++20中的一个。

,如果要根据成员的值删除范围中的所有元素,可以编写以下代码:

auto [begin, end] = std::ranges::remove(inventory, name, &Item::name);     
inventory.erase(begin, end);    
这是一个例子

如果只想删除第一项,可以编写:

inventory.erase(std::ranges::find(inventory, name, &Item::name));     
在这种情况下,您需要确保该项存在于该范围内,您可以通过与该范围的
end
进行比较来实现这一点


这是一个。

请在问题中包含a和编译器错误调试器告诉您什么?p.s.
hasItem
可以使用
std::any_of
。您可以通过const ref传递字符串,以防止复制。我只需使用一些调试器错误更新问题。请包含一个完整的示例。
库存是什么e> ?什么是
Item
?更新的代码包括struct和vector请在问题中包括a和编译器错误调试器告诉您什么?p.s.
hasItem
可以使用
std::any_of
。您可以通过const ref传递字符串,以防止复制。我只需使用一些调试器错误更新问题。p请包括一个完整的示例。什么是
库存
?什么是
项目
?代码更新包括结构和向量。您根本不需要
std::将
名称
移动到lambda中,您可以通过引用来捕获它:
[&](项目常量和项目){return Item.name==name}
然后您可以将
name
的声明更改为
const string&name
,以避免在调用
removietem()
hasItem()
时进行复制。如果您正在展示c++20解决方案,那么您应该展示如何在项目中使用
remove