以下是两种不同类型的std :: vector,例如:
std::vector<std::reference_wrapper<MyClass>> rv;
std::vector<MyClass> v;
在它们之间分配的可能方法是:
for (const auto& mc : rv) {
v.push_back(mc.get());
}
有效。但丑陋而且可能很慢。与比较相同:
bool is_same(std::vector<MyClass>& v, std::vector<std::reference_wrapper<MyClass>>& rv) {
if (v.size()!=rv.size()) {
return false;
}
for (size_t i = 0; i < v.size(); v++) {
if (v[i]!=rv[i].get()) {
return false;
}
}
return true;
}
有没有更好的方法来完成这项工作?聪明而快速。
答案 0 :(得分:5)
由于std::reference_wrapper
可隐式转换为对其所持类型的引用,因此您可以将{1}分配给MyClass
。
因此,使用另一个初始化一个更好的方法是适当的向量构造函数:
std::vector<MyClass> v(begin(rv), end(rv));
或者,如果你真的需要分配:
v.assign(begin(rv), end(rv));
您可以应用std::mismatch
算法进行比较,这要归功于std::reference_wrapper
提供的隐式转换:
bool is_same(std::vector<MyClass> const& v, std::vector<std::reference_wrapper<MyClass>> const& rv) {
return v.size() == rv.size() &&
end(v) == std::mismatch(begin(v), end(v), begin(rv), end(rv)).first;
}
作为一般经验法则,在自己编写循环之前咨询标准算法库总是好的。它通过为计算步骤提供动词和名词,使您自己的代码更具可读性。并且具有允许标准库可以提供的任何优化的好处。
正如 cppleaner 指出的那样,我应该更自己地咨询图书馆。通过简单调用std::equal
is_same
return std::equal(begin(v), end(v), begin(rv), end(rv));
答案 1 :(得分:0)
惯用is_same实现:
bool is_same(std::vector<MyClass>& v, std::vector<std::reference_wrapper<MyClass>>& rv) {
return std::equal(begin(v), end(v), begin(rv), end(rv),
[](const MyClass& c, const std::reference_wrapper<MyClass>& rc) {
return c == rc.get();
});
}
或者,您可以编写自定义:
class MyClass {
bool operator ==(const MyClass&);
};
bool operator != (const MyClass&, const MyClass&);
bool operator == (const MyClass&, const std::reference_wrapper<MyClass>&);
bool operator == (const std::reference_wrapper<MyClass>&, const MyClass&);
bool operator != (const MyClass&, const std::reference_wrapper<MyClass>&);
bool operator != (const std::reference_wrapper<MyClass>&, const MyClass&);
和客户端代码(这是多余的:您可以将实现用作操作):
bool is_same(const std::vector<MyClass>& v,
const std::vector<std::reference_wrapper<MyClass>>& rv) {
return v == rv;
}
注意:尽可能考虑在参数上使用const。