将唯一指针的向量复制到新向量中

use*_*224 7 c++ const vector c++11

当我编译下面的代码时,我得到一个编译错误:

std::vector<std::unique_ptr<boxIndex>> tmpVec;
for(const auto& it: hrzBoxTmpMap){
    for(const auto& it2: hrzBoxVec){
        std::copy_if(hrzBoxVec.begin(), hrzBoxVec.end(), tmpVec.begin(), [&](std::unique_ptr<boxIndex>& p)
        {
            return !(it.second == p->getTop() &&
                     it.first != p->getLeft() );
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

编译错误是:

/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_algo.h: 

> In instantiation of ‘_OIter std::copy_if(_IIter, _IIter, _OIter,
> _Predicate) [with _IIter = __gnu_cxx::__normal_iterator<std::unique_ptr<boxIndex>*, std::vector<std::unique_ptr<boxIndex> > >; _OIter =
> __gnu_cxx::__normal_iterator<std::unique_ptr<boxIndex>*, std::vector<std::unique_ptr<boxIndex> > >; _Predicate =
> smoothHrzIndexing(std::vector<std::unique_ptr<boxIndex>
> >&)::<lambda(std::unique_ptr<boxIndex>&)>]’: test_word_2.cpp:282:5:   required from here
> /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_algo.h:990:6:
> error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>&
> std::unique_ptr<_Tp, _Dp>::operator=(const std::unique_ptr<_Tp, _Dp>&)
> [with _Tp = boxIndex; _Dp = std::default_delete<boxIndex>]’ In file
> included from
> /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/memory:86:0,
>                  from test_word_2.cpp:8: /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/unique_ptr.h:263:19:
> error: declared here
Run Code Online (Sandbox Code Playgroud)

有人可以帮我吗?

Die*_*ühl 7

你可以做的是使用std::move_iterator<...>例如下面的东西(这是SSCCE展示关键点:

#include <iostream>
#include <iterator>
#include <vector>
#include <memory>

int main()
{
    std::vector<std::unique_ptr<int>> boxVec;
    boxVec.emplace_back(new int(1));
    boxVec.emplace_back(new int(17));
    boxVec.emplace_back(new int(3));
    std::vector<std::unique_ptr<int>> tmpVec;
    std::copy_if(std::make_move_iterator(boxVec.begin()),
                 std::make_move_iterator(boxVec.end()),
                 std::back_inserter(tmpVec),
                 [&](std::unique_ptr<int> const& p){
                     return *p == 17; });
    for (auto const& x: boxVec) {
        (x? std::cout << *x: std::cout << "<null>") << " ";
    }
    std::cout << "\n";
}
Run Code Online (Sandbox Code Playgroud)

取消引用std::move_iterator<It>将返回迭代器值类型的合适rvalue.由于使用了rvalue std::move(*it),因此它是参考.也就是说,在实际移动该值之前,该值不会被盗.比较使用a const&,即它不会窃取价值.赋值将成为右值赋值.该代码还用于std::back_inserter()安排足够的元素在目标中.

我不认为这确实是一个可靠的解决方案,但我也不认为有一个算法std::move_if()(或任何算法的自定义导致相同的行为).为了真正处理有条件移动的对象,我认为你对传递给谓词的值和对象的分配方式有不同的访问机制(属性映射可以解决这些问题但是没有提议,但是,将它们添加到C++中标准).


Mr.*_*C64 0

std::unique_ptr可移动的,不可复制的
因此,您不能std::copy_if()unique_ptr实例一起使用。

如果你真的想使用std::copy_if(),那么你可以使用,而std::shared_ptr不是std::unique_ptr,然后如果你想摆脱旧的矢量内容,只需使用例如销毁它即可vector::clear()

或者,如果shared_ptr对您来说开销太大,或者在任何情况下您只想要unique_ptrs 的向量,那么您可能需要考虑使用擦除删除习惯用法就地删除不需要std::remove_if()向量元素