如何将 Phoenix 表达式与 boost::transform_iterator 一起使用?
<更新>像往常一样,我的问题是错误的。实际的问题是:为什么transform_iterator不使用传统的result_of<>元函数来确定返回类型,而不是直接访问 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
?
<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. 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? boost::transform_iterator seems to expect this, and from looking at the src of it, I don't see a simple work around.
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):
/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
). 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.
Is there a provided wrapper or some other mechanism in phoenix or lambda to expose result_type
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来这个问题已在 boost trunk (参见第 51 行,
result_of<>
,而不是间接的UnaryFunc::result_type
)。所以这在 1.44 及更高版本中不应该是问题。这是 boost < 的解决方法1.44。仅当未提供
Reference
模板参数时,transform_iterator 实例化才会访问UnaryFunc::result_type
。因此,一个技巧是将 make_transform_iterator 替换为调用 result_of<> 的版本。 UnaryFunc 上的 meta 函数并将结果用作参考模板参数。It looks like this is fixed in the boost trunk (see line 51,
result_of<>
instead of an indirectUnaryFunc::result_type
). So this shouldn't be an issue in 1.44 and above.Here's a workaround for boost < 1.44. The transform_iterator instantiation accesses
UnaryFunc::result_type
only if theReference
template parameter is not provided. 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.