3

下面以两种不同类型的 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;
}

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

4

2 回答 2

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指出的那样,我自己应该更仔细地咨询图书馆。is_same可以通过一个简单的调用来更容易地实现std::equal

return std::equal(begin(v), end(v), begin(rv), end(rv));
于 2016-12-27T09:01:06.543 回答
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。

于 2016-12-27T09:05:10.513 回答