|
Boost Users : |
Subject: [Boost-users] [type_erasure] Problem with iterators
From: Marco Guazzone (marco.guazzone_at_[hidden])
Date: 2015-01-24 02:56:54
Hi,
I'm new to the Type Erasure library.
I need to write a base class with type-erased forward iterators. To do
so I've taken inspiration from the print_sequence.cpp example I've
found in the Type Erasure source tree.
At the end of the email there is the whole code of my tentative,
called "erasure.cpp".
Unfortunately, I've problems (presumably) with const iterators which
cause the following compile error:
$ g++ -Wall -Wextra -pedantic -std=c++11 -I$HOME/sys/src/git/boost -o
erasure erasure.cpp -lm
*** [begin error] ***
In file included from
/home/sguazt/sys/src/git/boost/boost/type_erasure/iterator.hpp:20:0,
from erasure.cpp:2:
/home/sguazt/sys/src/git/boost/boost/type_erasure/operators.hpp: In
instantiation of âstatic R boost::type_erasure::dereferenceable<R,
T>::apply(const T&) [with R = double&; T =
__gnu_cxx::__normal_iterator<const double*, std::vector<double> >]â:
/home/sguazt/sys/src/git/boost/boost/type_erasure/detail/instantiate.hpp:91:9:
required from âstatic void
boost::type_erasure::detail::instantiate_concept7::apply(Concept*,
Map*) [with Concept =
boost::mpl::vector<boost::type_erasure::forward_iterator<>,
boost::type_erasure::same_type<boost::type_erasure::deduced<boost::type_erasure::iterator_value_type<boost::type_erasure::_self>
>, double>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>; Map =
boost::mpl::map1<boost::mpl::pair<boost::type_erasure::_self,
__gnu_cxx::__normal_iterator<const double*, std::vector<double> > >
>]â
/home/sguazt/sys/src/git/boost/boost/type_erasure/any.hpp:225:13:
required from âboost::type_erasure::any<Concept, T>::any(U&&) [with U
= __gnu_cxx::__normal_iterator<const double*, std::vector<double> >&;
Concept = boost::mpl::vector<boost::type_erasure::forward_iterator<>,
boost::type_erasure::same_type<boost::type_erasure::deduced<boost::type_erasure::iterator_value_type<boost::type_erasure::_self>
>, double>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>; T =
boost::type_erasure::_self]â
erasure.cpp:36:40: required from âstd::vector<_RealType>
base<T>::foo(IterT, IterT) [with IterT =
__gnu_cxx::__normal_iterator<const double*, std::vector<double> >; T =
double]â
erasure.cpp:77:73: required from here
/home/sguazt/sys/src/git/boost/boost/type_erasure/operators.hpp:134:44:
error: invalid initialization of reference of type âdouble&â from
expression of type âconst doubleâ
static R apply(const T& arg) { return *arg; }
*** [/end error] ***
The GCC version is 4.9.2.
Here below is the content of "erasure.cpp". If I comment lines below
the comment "THE FOLLOWING WON'T COMPILE" I get no error. So the
problem is due to the use of cbegin/cend.
*** [erasure.cpp] ***
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/iterator.hpp>
#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/same_type.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/smart_ptr.hpp>
#include <cmath>
#include <cstddef>
#include <iostream>
#include <iterator>
#include <vector>
namespace mpl = boost::mpl;
namespace te = boost::type_erasure;
template <typename T>
using fwd_iter_impl_t = te::any<
mpl::vector<
te::forward_iterator<>,
te::same_type<te::forward_iterator<>::value_type,T>>>;
template <typename T>
class base
{
protected:
typedef fwd_iter_impl_t<T> fwd_iter_type;
public:
virtual ~base() { }
template <typename IterT>
std::vector<T> foo(IterT first, IterT last)
{
return this->do_foo(first, last);
}
private:
virtual std::vector<T> do_foo(fwd_iter_type first, fwd_iter_type last) = 0;
}; // base
template <typename T>
class derived: public base<T>
{
private:
typedef typename base<T>::fwd_iter_type fwd_iter_type;
std::vector<T> do_foo(fwd_iter_type first, fwd_iter_type last)
{
const std::ptrdiff_t n = std::distance(first, last);
std::vector<T> res(n);
for (std::size_t i = 0; first != last; ++first, ++i)
{
res[i] = std::pow(*first,i)/n;
}
return res;
}
}; // derived
int main()
{
std::vector<double> dv;
dv.push_back(5);
dv.push_back(8);
dv.push_back(11);
boost::scoped_ptr< base<double> > p_base(new derived<double>());
// begin/end
const std::vector<double> foos = p_base->foo(dv.begin(), dv.end());
for (std::size_t i = 0; i < foos.size(); ++i)
{
std::cout << "foos[" << i << "]: " << foos[i] << std::endl;
}
//--- THE FOLLOWING WON'T COMPILE
// cbegin/cend
const std::vector<double> cfoos = p_base->foo(dv.cbegin(), dv.cend());
for (std::size_t i = 0; i < cfoos.size(); ++i)
{
std::cout << "cfoos[" << i << "]: " << cfoos[i] << std::endl;
}
}
*** [/erasure.cpp] ***
Thank you very much for your help.
Best,
-- Marco
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net