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