When I compile the below code, I get a compilation error:
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() );
});
}
}
The compilation error is:
/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
Can someone help me on this?
What you could do is to use std::move_iterator<...>
using, e.g., something like below (this is a SSCCE demonstrating the crucial point:
#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";
}
Dereferencing a std::move_iterator<It>
will return a suitable rvalue of the iterator's value type. Since the rvalue is obtained using std::move(*it)
, it is a reference. That is, the value isn't stolen until the value is actually moved. The comparison uses a const&
, i.e., it won't steal the value. The assignment will become an rvalue assignment. The code also uses std::back_inserter()
to arrange for enough elements to be in the destination.
I don't think this is really a solid solution but I also don't think there is an algorithm like std::move_if()
(or a customization of any algorithm resulting in the same behavior). To really deal with conditionally moving objects I think you'd different access mechanism for the values passed into the predicate and the the way objects are assigned (property maps would address these issues but there is no proposal, yet, to add them to the C++ standard).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With