提问人:prestokeys 提问时间:12/30/2022 最后编辑:prestokeys 更新时间:12/30/2022 访问量:65
标准库类上的自定义赋值运算符
Custom assignment operator on standard library classes
问:
例如,如果我想进行作业
std::vector<int> a;
std::vector<std::pair<std::string, int>> b;
a = b; // a takes all the second components of the pairs in b
这样的自定义分配是否可行?
答:
6赞
Some programmer dude
12/30/2022
#1
您似乎想要的是将一个容器转换为另一个容器。这通常通过适当命名的 std::transform
标准函数来完成:
std::vector<int> a(b.size()); // Set as same size as the source vector
std::transform(begin(b), end(b), begin(a), [](auto const& pair)
{
return pair.second; // Use the second value of each pair from the source
});
评论
0赞
Mooing Duck
12/30/2022
我可能会选择而不是调整大小,但这是一般答案std::back_inserter
0赞
Some programmer dude
12/30/2022
@MooingDuck 这将导致数据的多次重新分配,最好在知道数据后设置大小。
1赞
Mooing Duck
12/30/2022
reserve
然后。如果引发异常,调整大小会留下问题
2赞
463035818_is_not_an_ai
12/30/2022
#2
你能重载把所有元素推送到吗?=
a = b;
second
a
不。撇开类型重载运算符的其他问题不谈,只能作为成员函数实现。不能将成员添加到 。std
=
std::vector<int>
你能重载把所有元素推送到吗?=
a = b;
second
a
是的。不能重载 ,但可以重载其他类型:=
std::vector
#include <vector>
#include <utility>
#include <string>
struct pick_second_vector_ref {
std::vector<int>& t;
template <typename Source>
void operator=(const Source& s) {
for (const auto& e : s) {
t.push_back(e.second);
}
}
};
int main() {
std::vector<int> a;
std::vector<std::pair<std::string, int>> b {{"foo",42}};
pick_second_vector_ref r{a};
r = b; // a takes all the second components of the pairs in b
}
但是,这只是为了说明当您的问题过于字面意思时会发生什么。通常,命名函数比执行意外操作的运算符重载要清晰得多。上面的内容应该看起来像这样:main
int main() {
std::vector<int> a;
std::vector<std::pair<std::string, int>> b {{"foo",42}};
copy_second(a,b); // no comment needed here because the code
// explains itself !!
}
...附言...
我在很多地方都使用了 =,现在我已经更改了左向量操作数,我将不得不在我使用的所有地方放置必要的变换函数。
=
还行。去吧。更改代码。这将是简单的修复,因为代码中出现的所有错误都是编译器错误。请记住:代码只写一次,但读很多次。从长远来看,您花在修复上将节省 5 分钟,因为读者不必怀疑它实际上做了什么(只有当代码本身无法清楚地表达代码时,才需要注释来解释代码,这里的情况并非如此)。=
=
=
评论
=
不能是非会员:en.cppreference.com/w/cpp/language/operators。