On Sat, Jan 24, 2015 at 9:29 PM, Steven Watanabe <watanabesj@gmail.com> 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