повысить слияние и правильность

Я учусь стимулировать синтез и пытаюсь взглянуть на std::vector<boost::fusion::vector<int,double,double> >, Код кажется простым, но я столкнулся с некоторыми проблемами с const. Я явно неправильно понимаю кое-что о const и хотел бы, чтобы кто-то объяснил, где я иду не так.

Код:

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

Код не компилируется в retVal.push_back() из-за проблемы с кастом конст. Я пробовал несколько вариантов удаления и добавления некоторых константных ключевых слов, но не преуспел в программировании с помощью перестановок и предпочел бы понять, что я делаю.

У кого-нибудь есть мысли? Кстати const в определении функции sum а также c должен остаться.

РЕДАКТИРОВАТЬ: я забыл упомянуть, что b заливка x который является std::vector<fusion::vector<int, double, double> >

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

1

Решение

Есть две непосредственные проблемы с вашим кодом:

  • ты вычисляешь fusion::as_nview<N>(*it) и попытаться сохранить его, как если бы это было fusion::result_of::as_nview<T::value_type, N>::type; на самом деле это fusion::result_of::as_nview<T::value_type const, N>::type (*it имеет тип T::const_reference); это источник вашего constсвязанные ошибки.

  • Вы пытаетесь накапливать полученные взгляды, но, насколько я могу судить по Fusion Docs, допустимыми операциями в таком представлении являются в основном операции последовательности Fusion Random Access. В частности, вы не можете добавить два представления вместе или создать одно по умолчанию. Вот пример возможного исправления (ни в коем случае не единственным способом), не проверенный на самом деле:

    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());
    

    где add_views это функтор, который возвращает что-то в духе lhs + at<0>(rhs), Обратите внимание, что это решение действительно имеет смысл, только если вы собираетесь c сделать взгляды длины ровно одним.

1

Другие решения

Ваш Sequence тип не T::value_type, его const T::value_type, Попробуйте написать typedef const typename T::value_type etype;,

0

По вопросам рекламы [email protected]