将 mpl lambda 表达式作为模板参数传递

发布于 2024-12-12 14:05:25 字数 2892 浏览 1 评论 0 原文

我正在尝试编写一个类似于 boost::mpl::find_if 的元函数,但不同之处在于它将从末尾开始遍历序列。我收到编译错误,我猜这些错误来自作为我的元函数的参数传递的 mpl::lambda 的计算。如果有人指出我做错了什么,我将非常感激。

现在我正在尝试一个懒惰的解决方案(装饰原来的 find_if ):

#include <boost/mpl/reverse.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/distance.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/advance.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/lambda.hpp>


using boost::mpl::reverse;
using boost::mpl::find_if;
using boost::mpl::distance;
using boost::mpl::end;
using boost::mpl::advance;
using boost::mpl::prior;
using boost::mpl::lambda;

template<typename SEQ, typename pred>
struct rfind_if {
private:
  // find the element in the reversed container    
  typedef typename reverse<SEQ>::type   rev_SEQ;
  typedef typename lambda<pred>::type   expanded_pred;    
  typedef typename find_if<rev_SEQ, expanded_pred>::type   rev_iter;
  // compute the distance of the iterator
  typedef typename distance<rev_iter, typename end<rev_SEQ>::type >::type  dist;
public:
  //compute the iterator
  typedef typename advance<typename begin<SEQ>::type, typename prior<dist>::type>::type   type;
};

问题是当尝试使用这个函数时:

typedef vector_c<int, 1, 2, 3, 6, 5, 4>::type  test_vect;
typedef find<test_vect, int_<6>::type>::type  it_cur;
typedef rfind_if<test_vect, lambda<less<deref<it_cur>::type, _1> >::type >::type  it_swap;
std::cout << "it_swap=" << deref<it_swap>::type::value << "\n\n";

我得到了神秘的错误,我猜这些错误来自 lambda 计算:

 /usr/include/boost/mpl/aux_/preprocessed/gcc/less.hpp:60: error: no type named ‘tag’ in ‘struct mpl_::void_’ (some more template noise)
 /usr/include/boost/mpl/not.hpp:43: error: ‘value’ is not a member of ‘boost::mpl::aux::nested_type_wknd<boost::mpl::aux::iter_apply1 (some more template noise)
 /usr/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp:62: error: no type named ‘type’ in ‘struct boost::mpl::apply2<boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred (some more template noise)
 ...and much more...

我已经测试了 rfind_if 的内部结构(没有将 lambda 作为模板参数传递)并且它起作用了,naming:

typedef vector_c<int, 1, 2, 3, 6, 5, 4>::type               test_vect;
typedef boost::mpl::reverse<test_vect>::type                rev_SEQ;
typedef find_if<rev_SEQ, less<int_<5>, _1> >::type          rev_iter;
typedef distance<rev_iter, end<rev_SEQ>::type >::type       dist;
typedef advance<begin<test_vect>::type, prior<dist>::type>::type    it_begin;

boost::mpl::for_each< rev_SEQ >( value_printer() );

产生了正确的结果

我知道我的函数远非高效,但现在我想了解这个问题。之后我会写一个正确的实现。

此致

I'm trying to write a metafunction similar to boost::mpl::find_if but with the difference that it will traverse the sequence starting from the end. I am getting compilation errors which I guess come from computation of mpl::lambda passed as an argument of my metafunction. I would be very grateful on any pointers on what I am doing wrong.

Right now I'm trying a lazy solution (decorating the original find_if):

#include <boost/mpl/reverse.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/distance.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/advance.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/lambda.hpp>


using boost::mpl::reverse;
using boost::mpl::find_if;
using boost::mpl::distance;
using boost::mpl::end;
using boost::mpl::advance;
using boost::mpl::prior;
using boost::mpl::lambda;

template<typename SEQ, typename pred>
struct rfind_if {
private:
  // find the element in the reversed container    
  typedef typename reverse<SEQ>::type   rev_SEQ;
  typedef typename lambda<pred>::type   expanded_pred;    
  typedef typename find_if<rev_SEQ, expanded_pred>::type   rev_iter;
  // compute the distance of the iterator
  typedef typename distance<rev_iter, typename end<rev_SEQ>::type >::type  dist;
public:
  //compute the iterator
  typedef typename advance<typename begin<SEQ>::type, typename prior<dist>::type>::type   type;
};

The problem is that When trying to use this function:

typedef vector_c<int, 1, 2, 3, 6, 5, 4>::type  test_vect;
typedef find<test_vect, int_<6>::type>::type  it_cur;
typedef rfind_if<test_vect, lambda<less<deref<it_cur>::type, _1> >::type >::type  it_swap;
std::cout << "it_swap=" << deref<it_swap>::type::value << "\n\n";

I get cryptic errors which, I guess, come from lambda computations:

 /usr/include/boost/mpl/aux_/preprocessed/gcc/less.hpp:60: error: no type named ‘tag’ in ‘struct mpl_::void_’ (some more template noise)
 /usr/include/boost/mpl/not.hpp:43: error: ‘value’ is not a member of ‘boost::mpl::aux::nested_type_wknd<boost::mpl::aux::iter_apply1 (some more template noise)
 /usr/include/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp:62: error: no type named ‘type’ in ‘struct boost::mpl::apply2<boost::mpl::protect<boost::mpl::aux::iter_fold_if_pred (some more template noise)
 ...and much more...

I've tested the internals of rfind_if (without passing the lambda as a template argument) and it worked, naming:

typedef vector_c<int, 1, 2, 3, 6, 5, 4>::type               test_vect;
typedef boost::mpl::reverse<test_vect>::type                rev_SEQ;
typedef find_if<rev_SEQ, less<int_<5>, _1> >::type          rev_iter;
typedef distance<rev_iter, end<rev_SEQ>::type >::type       dist;
typedef advance<begin<test_vect>::type, prior<dist>::type>::type    it_begin;

boost::mpl::for_each< rev_SEQ >( value_printer() );

produced correct results

I know that my function is far from efficient, but right now I want to understand the problem. I will write a proper implementation afterwards.

Best Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

喜爱皱眉﹌ 2024-12-19 14:05:25

据我所知, rfind_if 不是错误的原因,而是代码
这个问题似乎取消了对 test_vectend 的引用。

1)
vector_c 中元素的类型似乎是 integral_c,而不是
int_
所以 find::type>::typetest_vectend
因此,在 deref::type 中取消引用 it_cur 是无效的。

2)
如果您的意思是 less, _1> by less::type, _1>
由于 test_vect 没有这样的元素,因此 rfind_if<...>::type
再次是 test_vectend
因此,在 deref::type::value 中取消引用它是无效的。

解决完以上问题后,
该代码可以在 ideone 上编译。

As far as I see, rfind_if isn't the cause of the error, but the code in
the question seems to dereference the end of test_vect.

1)
The type of the elements in vector_c<int> seems integral_c<int>, not
int_.
So find<test_vect, int_<6>::type>::type is the end of test_vect.
Therefore dereferencing the it_cur in deref<it_cur>::type is invalid.

2)
If you mean less<int_<6>, _1> by less<deref<it_cur>::type, _1>,
since test_vect doesn't have such an element, rfind_if<...>::type is
again the end of test_vect.
So dereferencing it in deref<it_swap>::type::value is invalid.

After fixing the above issues,
the code could be compiled on ideone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文