|
Boost Users : |
Subject: Re: [Boost-users] [type_erasure] Problem with iterators
From: Marco Guazzone (marco.guazzone_at_[hidden])
Date: 2015-01-24 17:10:10
On Sat, Jan 24, 2015 at 9:29 PM, Steven Watanabe <watanabesj_at_[hidden]> wrote:
> AMDG
>
> On 01/24/2015 12:56 AM, Marco Guazzone wrote:
>> 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:
>>
>
> Iterators are mutable by default. If you want
> a const iterator, you need to specify the reference
> type. (If you look at the range print example,
> it uses forward_iterator<_iter, const _t&>)
>
[big cut]
Hi Steven,
Probably I haven't correctly understand your suggestion since now that
I've commented the definition of "fwd_iter_impl_t" and replaced the
"typedef" definition in "base" class with the following one:
struct _t: te::precision { };
struct _iter: te::precision { };
//...
typedef te::any< mpl::vector< te::forward_iterator<_iter, const _t&>,
te::same_type<_t,
te::forward_iterator<_iter, const _t&>::value_type>>,
_iter> fwd_iter_type;
I get an error when calling the std::pow function:
erasure.cpp: In instantiation of âstd::vector<_RealType>
derived<T>::do_foo(derived<T>::fwd_iter_type,
derived<T>::fwd_iter_type) [with T = double; derived<T>::fwd_iter_type
= boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::forward_iterator<_iter,
const _t&>, boost::type_erasure::same_type<_t,
boost::type_erasure::deduced<boost::type_erasure::iterator_value_type<_iter>
> > >, _iter>]â:
erasure.cpp:79:1: required from here
erasure.cpp:51:39: error: no matching function for call to
âpow(boost::type_erasure::rebind_any<boost::type_erasure::concept_interface<boost::type_erasure::assignable<_iter,
_iter>, boost::type_erasure::concept_interface<boost::type_erasure::incrementable<_iter>,
boost::type_erasure::concept_interface<boost::type_erasure::same_type<_t,
_t>, boost::type_erasure::any_base<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::forward_iterator<_iter,
const _t&>, boost::type_erasure::same_type<_t,
boost::type_erasure::deduced<boost::type_erasure::iterator_value_type<_iter>
> > >, _iter> >, _iter, void>, _iter, void>, _iter, void>, const
_t&>::type, std::size_t&)â
res[i] = std::pow(*first,i)/n;
(The error message continues by listing possible candidates)
Here below is the new code:
*** [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;
struct _t: te::placeholder { };
struct _iter: te::placeholder { };
template <typename T>
class base
{
protected:
typedef te::any< mpl::vector< te::forward_iterator<_iter, const _t&>,
te::same_type<_t,
te::forward_iterator<_iter, const _t&>::value_type>>,
_iter> fwd_iter_type;
public:
virtual ~base() { }
template <typename IterT>
std::vector<T> foo(IterT first, IterT last) const
{
return this->do_foo(first, last);
}
private:
virtual std::vector<T> do_foo(fwd_iter_type first, fwd_iter_type
last) const = 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
{
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] ***
Where am I wrong?
Thank you for your time.
-- 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