【问题标题】:Using a state preserving functor with boost::transform_iterator使用带有 boost::transform_iterator 的状态保持函子
【发布时间】:2012-07-30 01:52:44
【问题描述】:

我有如下仿函数:

 struct Functor{
    //Global statistics for all objects seen;

    Statistics stats;

    Object operator( const Object & obj) const
    {
          //Copy Object
          Object tmp = obj;
          compute(tmp);
          return tmp;
    }


    void compute( Object & obj );
       //Compute on Object & store in Object 
       :
       :
       stats += obj; <---compute stats about the object itself.
    }
 }

函子以下列方式与boost::transform_iterator 一起使用:

SomeDataStructure ds;

boost::transform_iterator< Functor, SomeDataStructure::iterator  > iBegin,iEnd;

iBegin = boost::make_transform_iterator( ds.begin(),Functor() );
iEnd   = boost::make_transform_iterator( ds.end(),Functor() );

AnotherMethod(iBegin,iEnd);

关于上面的代码,我有两个问题:

1) Functor 通过值传递给迭代器。因此,即使我使用以下代码,我也无法从函子中提取任何值:

iBegin.functor().stats;

有没有更好的方法?

2) 仿函数通常会填充 Object 类型的不完整对象。即计算对象的属性并将其存储回对象中。 operator() 需要一个来自 transform_iterator 类内部的 const 对象。目前,我制作了对象的副本并填充并返回它。我想摆脱这个不必要的副本,那么有什么办法吗?

PS:也欢迎替代解决方案。

【问题讨论】:

    标签: c++ boost iterator


    【解决方案1】:

    关于问题 1) 你可以使用 C++11 的 boost::ref std::ref

    boost::transform_iterator< std::reference_wrapper<Functor>, 
                               SomeDataStructure::iterator  > iBegin,iEnd;
    
    auto myFunctor = std::ref(Functor());
    iBegin = boost::make_transform_iterator( ds.begin(), myFunctor );
    iEnd   = boost::make_transform_iterator( ds.end(), myFunctor );
    

    关于2),如果不能通过非常量引用传递,最好是按值传递,避免自己做一个临时的:

    Object operator(Object obj) const
    {
          compute(obj);
          return obj;
    }
    

    这允许编译器执行复制省略并可能导致更少的复制。请参阅this article 了解更多信息。

    【讨论】:

    • 感谢您的回复。我可能错了,但 std::ref 是否也暴露了仿函数中定义的 typedef? transform_iterator 需要一个 result_type 没有它我会得到编译错误。
    • @SamratRoy 它不保留 typedef。如果你有 C++11(std::ref 需要它),那么你可以使用auto。当然,如果 boost 实现不使用它,这也无济于事。看起来您必须实现自己的类似引用的包装器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多