如何使用boost :: transform_iterator使用phoenix表达式?

时间:2010-06-22 04:29:28

标签: c++ boost boost-lambda boost-phoenix

<更新> 像往常一样,问题是错误的。实际问题是:为什么transform_iterator不使用传统的result_of<> metafunction来确定返回类型,而不是直接访问UnaryFunc :: result_type。通过解决方案发表答案。的< /更新>

具体来说,是否有一种方法可以使phoenix表达式为std :: unary_function概念预期显示result_type类型? boost :: transform_iterator似乎期待这个,并且通过查看它的src,我看不到简单的解决方法。

这里有一些代码可以重现我一直遇到的问题:

#include <boost/iterator/transform_iterator.hpp>
#include <boost/spirit/home/phoenix.hpp>
#include <numeric>
#include <iostream>

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

int main(void){
   int i[] = {4,2,5,3};

   std::cout <<
      std::accumulate(
         boost::make_transform_iterator(i,   _1*_1),
         boost::make_transform_iterator(i+4, _1*_1),
         0
      ) << std::endl;

   return 0;
}

编译错误消息的相关部分是(gcc 4.3.4,boost 1.43):

/usr/include/boost/iterator/transform_iterator.hpp:43: error: no type named ‘result_type’ in ‘struct boost::phoenix::actor<...

我对boost :: lambda(缺少result_type)也有同样的问题。我以为我过去看过make_transform_iterator和lambda的类似用法,现在我想知道我是不是想象它。

在phoenix或lambda中是否有提供的包装器或其他机制来公开result_type

1 个答案:

答案 0 :(得分:4)

boost trunk看来这已得到修复(请参阅第51行,result_of<>而不是间接UnaryFunc::result_type)。所以这不应该是1.44及以上的问题。

这是针对boost&lt;的解决方法1.44。仅当未提供UnaryFunc::result_type模板参数时,transform_iterator实例化才会访问Reference。因此,一个技巧是将make_transform_iterator替换为调用result_of&lt;&gt;的版本。 UnaryFunc上的元函数,并将结果用于参考模板参数。

#include <boost/iterator/transform_iterator.hpp>
#include <boost/utility.hpp>
#include <iterator>

template <class UnaryFunc, class Iterator>
boost::transform_iterator<
   UnaryFunc,
   Iterator,
   typename boost::result_of<
      UnaryFunc(typename std::iterator_traits<Iterator>::value_type)
   >::type
>
make_trans_it(Iterator it, UnaryFunc fun){
   return
      boost::transform_iterator<
         UnaryFunc,
         Iterator,
         typename boost::result_of<
            UnaryFunc(typename std::iterator_traits<Iterator>::value_type)
         >::type
      >(it, fun);
};