简体   繁体   English

提高融合和const正确性

[英]boost fusion and const correctness

I am learning boost fusion and am trying to take a view of a std::vector<boost::fusion::vector<int,double,double> > . 我正在学习Boost融合,并试图了解std::vector<boost::fusion::vector<int,double,double> > The code appears simple but I appear to be running into some problems with const. 代码看起来很简单,但是我似乎遇到了一些const问题。 I clearly misunderstand something about const and would love for someone to explain where I am going wrong. 我显然误解了有关const的某些知识,并希望有人解释我要去哪里。

The code: 编码:

template<int N, class T>
struct viewTraits{
    typedef typename T::value_type etype;
    typedef typename boost::fusion::result_of::as_nview<etype, N>::type netype;
    typedef std::vector<netype> result_type;
};

template <int N, typename T>
typename viewTraits<N,T>::result_type c( T const &t ) 
{
   typename viewTraits<N, T>::result_type retVal;  
    for (typename T::const_iterator it(t.begin());it<t.end();++it){
        retVal.push_back(fusion::as_nview<N>(*it));
    } 
    return retVal;
}

template <typename Container>
typename Container::value_type sum( Container const &container )
{
    typedef typename Container::value_type value_type;
    return std::accumulate( container.begin(), container.end(), value_type() );
}

int main(){
    typedef fusion::vector<int, double, double>             row;
    typedef std::vector<row>                                                container;

    container x;
    b( x, 200 );
    std::cout << sum(c<1>(x)) << std::endl;
}

The code fails to compile at retVal.push_back() because of an issue with casting const. 由于强制转换const的问题,代码无法在retVal.push_back()上编译。 I tried several permutations of removing and adding some const keywords but have not been successful at programming by permutation and would rather understand what I am doing. 我尝试了一些删除和添加一些const关键字的排列方式,但是通过排列方式编程并没有成功,并且希望了解我在做什么。

Anyone have any thoughts? 有人有什么想法吗? BTW the const in the function definition of sum and c must stay. 顺便说一句, sumc函数定义中的const必须保留。

EDIT: I forgot to mention that b fills x which is a std::vector<fusion::vector<int, double, double> > 编辑:我忘了提到b填充x这是一个std::vector<fusion::vector<int, double, double> >

EDIT2: The corrected code: EDIT2:更正的代码:

template<int N, class T>
struct viewTraits{
    typedef typename T::value_type etype;
    typedef typename fusion::result_of::as_nview<etype, N>::type netype;
    typedef typename fusion::result_of::at_c<netype,0>::type reference;
    typedef typename boost::decay<reference>::type value_type;
    typedef std::vector<value_type> result_type;
};

template <int N, typename T>
typename viewTraits<N,T>::result_type c( T const &t )
{
    typename viewTraits<N,T>::result_type retVal;

    for(typename T::const_iterator it(t.begin()); it<t.end();++it){
        retVal.push_back(fusion::deref(fusion::begin(fusion::as_nview<N>(*it))));
    }
    return retVal;
}

There are two immediate problems with your code: 您的代码有两个直接的问题:

  • you compute fusion::as_nview<N>(*it) and try to store it as if it were a fusion::result_of::as_nview<T::value_type, N>::type ; 您计算fusion::as_nview<N>(*it)并尝试将其存储为fusion::result_of::as_nview<T::value_type, N>::type in truth it is a fusion::result_of::as_nview<T::value_type const, N>::type ( *it has type T::const_reference ); 实际上,这是一个fusion::result_of::as_nview<T::value_type const, N>::type*it类型为T::const_reference ); this is the source of your const -related errors. 这是与const相关的错误的根源。

  • you try to accumulate the resulting views, but, as far I can tell from the Fusion docs , valid operations on such a view are mostly those of a Fusion Random Access Sequence. 您尝试累积结果视图,但是据我从Fusion文档可以看出,对此类视图的有效操作主要是Fusion随机访问序列的操作。 In particular you can't add two views together, or default construct one. 特别是您不能将两个视图加在一起,也不能默认构造一个。 Here's a lead to a possible fix (by no means the only way though), not actually tested: 这是一个可能的修复方法(虽然绝不是唯一的方法),但未经过实际测试:

     typedef typename Container::value_type view_type; typedef typename fusion::result_of::at_c<view_type, 0>::type reference; // boost::decay is from Boost.TypeTraits typedef typename boost::decay<reference>::type value_type; value_type zero = 0; return std::accumulate(container.begin(), container.end(), zero, add_views()); 

    where add_views is a functor that returns something in the spirit of lhs + at<0>(rhs) . 其中add_views是一个函子,它按照lhs + at<0>(rhs)的精神返回某些内容。 Note that this solution only really makes sense if you intend for c to make views of length exactly one. 请注意,只有当您打算让c使长度为1的视图时,此解决方案才真正有意义。

Your Sequence type isn't T::value_type , it's const T::value_type . 您的Sequence类型不是T::value_type ,它是const T::value_type Try writing typedef const typename T::value_type etype; 尝试编写typedef const typename T::value_type etype; .

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

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