如何比较和分配std :: vector <T>和std :: vector <std :: reference_wrapper <T >>?

Rin*_*o_D 3 c++ stl vector c++11 reference-wrapper

以下是两种不同类型的std :: vector,作为示例:

std::vector<std::reference_wrapper<MyClass>> rv;
std::vector<MyClass> v;
Run Code Online (Sandbox Code Playgroud)

在它们之间分配的可能方法是:

for (const auto& mc : rv) {
    v.push_back(mc.get());
}
Run Code Online (Sandbox Code Playgroud)

有用.但丑陋而且可能很慢.与比较相同:

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;
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来完成这项工作?聪明而快速.

Sto*_*ica 5

由于std::reference_wrapper可隐式转换为对其所持类型的引用,因此可以指定一个MyClass.因此,使用另一个初始化一个更好的方法是适当的向量构造函数:

std::vector<MyClass> v(begin(rv), end(rv));
Run Code Online (Sandbox Code Playgroud)

或者,如果你真的需要分配:

v.assign(begin(rv), end(rv));
Run Code Online (Sandbox Code Playgroud)

您可以通过应用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;
}
Run Code Online (Sandbox Code Playgroud)

作为一般的经验法则,在自己编写循环之前咨询标准算法库总是好的.它通过为计算步骤提供动词和名词,使您自己的代码更具可读性.并且具有允许标准库可以提供的任何优化的好处.


正如cppleaner指出的那样,我本应该更亲密地咨询图书馆.is_same通过简单的调用就可以更轻松地实现std::equal

return std::equal(begin(v), end(v), begin(rv), end(rv));
Run Code Online (Sandbox Code Playgroud)