简体   繁体   English

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

[英]How to use a phoenix expression with boost::transform_iterator?

<Update> As usual for me, the question was a wrong one. <更新>像我一样,问题是错误的。 The actual question is: why doesn't transform_iterator use the conventional result_of<> metafunction to determine the return type, instead of accessing UnaryFunc::result_type directly. 实际问题是:为什么transform_iterator不使用传统的result_of <>元函数来确定返回类型,而不是直接访问UnaryFunc :: result_type。 Posted an answer with a work around. 通过解决方案发表答案。 </Update> </更新>

Specifically, is there a way to make a phoenix expression expose a result_type type as expected for the std::unary_function concept? 具体来说,是否有一种方法可以使phoenix表达式暴露出result_type :: unary_function概念所期望的result_type类型? boost::transform_iterator seems to expect this, and from looking at the src of it, I don't see a simple work around. boost :: transform_iterator似乎期待这个,并且通过查看它的src,我看不到简单的解决方法。

Here's some code that reproduces the problem I've been having: 这里有一些代码可以重现我一直遇到的问题:

#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;
}

The relavent portion of the error message from compiling this is (gcc 4.3.4, boost 1.43): 编译它的错误消息的相关部分是(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<...

I have the same problem with boost::lambda (missing result_type ). 我对boost :: lambda(缺少result_type )也有同样的问题。 I thought that I had seen similar usage for make_transform_iterator and lambda in the past, now I'm wondering if I just imagined it. 我以为我过去看过make_transform_iterator和lambda的类似用法,现在我想知道我是不是想象它。

Is there a provided wrapper or some other mechanism in phoenix or lambda to expose result_type ? 在phoenix或lambda中是否有提供的包装器或其他机制来公开result_type

It looks like this is fixed in the boost trunk (see line 51, result_of<> instead of an indirect UnaryFunc::result_type ). 看起来这是在boost trunk中修复的(参见第51行, result_of<>而不是间接的UnaryFunc::result_type )。 So this shouldn't be an issue in 1.44 and above. 所以这不应该是1.44及以上的问题。

Here's a workaround for boost < 1.44. 这是boost <1.44的解决方法。 The transform_iterator instantiation accesses UnaryFunc::result_type only if the Reference template parameter is not provided. 仅当未提供Reference模板参数时,transform_iterator实例化才会访问UnaryFunc::result_type So one trick is to replace make_transform_iterator with a version that calls the result_of<> meta function on the UnaryFunc and use the result for the Reference template parameter. 因此,一个技巧是将make_transform_iterator替换为在UnaryFunc上调用result_of <>元函数的版本,并将结果用于Reference模板参数。

#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);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM