C++ 如何在std算法中使用unique_ptr的变换迭代器

C++ 如何在std算法中使用unique_ptr的变换迭代器,c++,c++11,boost,C++,C++11,Boost,我试图调用向量的变换迭代器上的下限,之前曾问过类似的问题。这个问题稍微复杂一些,其他问题的解决方案并不容易应用 问题是一样的。在搜索过程中,当std实现将\uuuu first赋值给\uu middle时,调用unique_ptr operator=。在本例中,搜索变换对象列表(int->double)以定位等于或大于输入(double)的元素 int main() { 矢量{ 标准::使_唯一(0), 标准::使_唯一(1), 标准::使_独一无二(2), 标准::使_独一无二(3), 标准:

我试图调用
向量的变换迭代器上的
下限
之前曾问过类似的问题。这个问题稍微复杂一些,其他问题的解决方案并不容易应用

问题是一样的。在搜索过程中,当std实现将
\uuuu first
赋值给
\uu middle
时,调用unique_ptr operator=。在本例中,搜索变换对象列表(int->double)以定位等于或大于输入(double)的元素

int main()
{
矢量{
标准::使_唯一(0),
标准::使_唯一(1),
标准::使_独一无二(2),
标准::使_独一无二(3),
标准::使_独一无二(4),
};
自动转换=[](常量唯一性\u ptr&m)->双精度{
返回(*m)*2。;
}; 
auto first=boost::make_transform_迭代器(begin(v),transFunc);
auto last=boost::make_transform_迭代器(end(v),transFunc);
自动i=下限(第一、最后、5);
返回0;
}
我还尝试使用move_迭代器

  auto transFunc = [](unique_ptr<int>&& m) -> double {
    return (*m) * 2.;
  }; 
  auto first = boost::make_transform_iterator(
      make_move_iterator(begin(v)), transFunc);
  auto last = boost::make_transform_iterator(
      make_move_iterator(end(v)), transFunc);  
auto transFunc=[](唯一)->double{
返回(*m)*2。;
}; 
auto first=boost::make_transform_迭代器(
使_移动_迭代器(begin(v)),transFunc);
auto last=boost::make_transform_迭代器(
使_移动_迭代器(end(v)),transFunc);
看起来boost在经过转换的迭代器中没有传递正确的值


代码过去在VS2013中工作,但在VS2015或GNU中不工作。

lambda是不可复制的,默认情况下,
transform\u迭代器
保留可调用代码的副本

简单解决方案:
std::ref
std::cref

#include <memory>
#include <boost/iterator/transform_iterator.hpp>
#include <vector>

int main ()
{
    auto transFunc = [](const std::unique_ptr<int>& m) -> double { return (*m) * 2; }; 

    std::vector<std::unique_ptr<int>> v;
    v.push_back(std::make_unique<int>(0));
    v.push_back(std::make_unique<int>(1));
    v.push_back(std::make_unique<int>(2));
    v.push_back(std::make_unique<int>(3));
    v.push_back(std::make_unique<int>(4));

    auto first = boost::make_transform_iterator(begin(v), std::cref(transFunc));
    auto last  = boost::make_transform_iterator(end(v), std::cref(transFunc));  
    auto i = lower_bound(first, last, 5.);
}
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/phoenix.hpp>
#include <vector>
#include <memory>

using namespace boost::adaptors;
using namespace boost::phoenix::arg_names;

int main () {
    std::vector<std::unique_ptr<int>> v(5);
    boost::generate(v, [n=0]() mutable { return std::make_unique<int>(n++); });

    auto i = boost::lower_bound(
            v |
            indirected |
            transformed(2. * arg1), 5.);
}
#包括
#包括
#包括
int main()
{
自动转换=[](const std::unique_ptr&m)->double{return(*m)*2;};
std::向量v;
v、 向后推_(标准::使_唯一(0));
v、 向后推_(标准::使_唯一(1));
v、 向后推_(标准::使_唯一(2));
v、 推回(标准::使_唯一(3));
v、 推回(标准::使_唯一(4));
auto first=boost::make_transform_迭代器(begin(v),std::cref(transFunc));
auto last=boost::make_transform_迭代器(end(v),std::cref(transFunc));
自动i=下限(第一、最后、5);
}
或者: 改为创建可复制的可调用对象:

struct { double operator()(const std::unique_ptr<int>& m) const { return (*m) * 2; }; } transFunc;
struct{double operator()(const std::uniqueptr&m)const{return(*m)*2;};}transFunc;

#include <memory>
#include <boost/iterator/transform_iterator.hpp>
#include <vector>

int main ()
{
    auto transFunc = [](const std::unique_ptr<int>& m) -> double { return (*m) * 2; }; 

    std::vector<std::unique_ptr<int>> v;
    v.push_back(std::make_unique<int>(0));
    v.push_back(std::make_unique<int>(1));
    v.push_back(std::make_unique<int>(2));
    v.push_back(std::make_unique<int>(3));
    v.push_back(std::make_unique<int>(4));

    auto first = boost::make_transform_iterator(begin(v), std::cref(transFunc));
    auto last  = boost::make_transform_iterator(end(v), std::cref(transFunc));  
    auto i = lower_bound(first, last, 5.);
}
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/phoenix.hpp>
#include <vector>
#include <memory>

using namespace boost::adaptors;
using namespace boost::phoenix::arg_names;

int main () {
    std::vector<std::unique_ptr<int>> v(5);
    boost::generate(v, [n=0]() mutable { return std::make_unique<int>(n++); });

    auto i = boost::lower_bound(
            v |
            indirected |
            transformed(2. * arg1), 5.);
}
奖金

#include <memory>
#include <boost/iterator/transform_iterator.hpp>
#include <vector>

int main ()
{
    auto transFunc = [](const std::unique_ptr<int>& m) -> double { return (*m) * 2; }; 

    std::vector<std::unique_ptr<int>> v;
    v.push_back(std::make_unique<int>(0));
    v.push_back(std::make_unique<int>(1));
    v.push_back(std::make_unique<int>(2));
    v.push_back(std::make_unique<int>(3));
    v.push_back(std::make_unique<int>(4));

    auto first = boost::make_transform_iterator(begin(v), std::cref(transFunc));
    auto last  = boost::make_transform_iterator(end(v), std::cref(transFunc));  
    auto i = lower_bound(first, last, 5.);
}
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/phoenix.hpp>
#include <vector>
#include <memory>

using namespace boost::adaptors;
using namespace boost::phoenix::arg_names;

int main () {
    std::vector<std::unique_ptr<int>> v(5);
    boost::generate(v, [n=0]() mutable { return std::make_unique<int>(n++); });

    auto i = boost::lower_bound(
            v |
            indirected |
            transformed(2. * arg1), 5.);
}
#包括
#包括
#包括
#包括
#包括
使用名称空间boost::适配器;
使用名称空间boost::phoenix::arg_名称;
int main(){
std::向量v(5);
boost::generate(v,[n=0]()可变{return std::make_unique(n++);});
自动i=boost::下限(
五|
间接的|
转化(2.*arg1),5.);
}

刚刚意识到,如果我们使用phoenix,我们不需要单独进行间接寻址:@CandyChiu当然可以,但它可能也有助于降低性能