boost::any_range with an abstract class reference

Consider the following code: #include <vector> #include <boost\range\any_range.hpp> #include <boost\range\adaptors.hpp> struct IFooBar { virtual void func() = 0; }; typedef boost::any_range<IFooBar, boost::random_access_traversal_tag, const IFooBar&, std::ptrdiff_t> FooBarRange; int main() { std::vector<std::unique_ptr<IFooBar>> vec; FooBarRange range = vec | boost::adaptors::indirected; return 0; } Compilation fails with the following error ( looks like any_range value is supposed to be copy-constructable? ) Is there any workaround? boost_1_54_0, MSVC 2010 1>c:\users\voivoid\libs\boost_1_54_0\boost\range\detail\any_iterator_interface.hpp(90): error C2259: 'IFooBar' : cannot instantiate abstract class 1> due to following members: 1> 'void IFooBar::func(void)' : is abstract 1> c:\users\voivoid\projects\cpptestapp\cpptestapp\main.cpp(9) : see declaration of 'IFooBar::func' 1> c:\users\voivoid\libs\boost_1_54_0\boost\range\detail\any_iterator_interface.hpp(93) : see reference to class template instantiation 'boost::range_detail::any_single_pass_iterator_interface<Reference,Buffer>' being compiled 1> with 1> [ 1> Reference=IFooBar, 1> Buffer=boost::any_iterator_buffer<64> 1> ] 1> c:\users\voivoid\libs\boost_1_54_0\boost\range\detail\any_iterator_interface.hpp(101) : see reference to class template instantiation 'boost::range_detail::any_single_pass_iterator_interface<Reference,Buffer>' being compiled 1> with 1> [ 1> Reference=const IFooBar &, 1> Buffer=boost::any_iterator_buffer<64> 1> ] 1> c:\users\voivoid\libs\boost_1_54_0\boost\range\detail\any_iterator_interface.hpp(123) : see reference to class template instantiation 'boost::range_detail::any_forward_iterator_interface<Reference,Buffer>' being compiled 1> with 1> [ 1> Reference=const IFooBar &, 1> Buffer=boost::any_iterator_buffer<64> 1> ] 1> c:\users\voivoid\libs\boost_1_54_0\boost\range\detail\any_iterator_interface.hpp(151) : see reference to class template instantiation 'boost::range_detail::any_bidirectional_iterator_interface<Reference,Buffer>' being compiled 1> with 1> [ 1> Reference=const IFooBar &, 1> Buffer=boost::any_iterator_buffer<64> 1> ] 1> c:\users\voivoid\libs\boost_1_54_0\boost\range\detail\any_iterator.hpp(452) : see reference to class template instantiation 'boost::range_detail::any_random_access_iterator_interface<Reference,Difference,Buffer>' being compiled 1> with 1> [ 1> Reference=const IFooBar &, 1> Difference=ptrdiff_t, 1> Buffer=boost::any_iterator_buffer<64> 1> ] 1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(385) : see reference to class template instantiation 'boost::range_detail::any_iterator<Value,Traversal,Reference,Difference,Buffer>' being compiled 1> with 1> [ 1> Value=IFooBar, 1> Traversal=boost::random_access_traversal_tag, 1> Reference=const IFooBar &, 1> Difference=ptrdiff_t, 1> Buffer=boost::any_iterator_buffer<64> 1> ] 1> c:\users\voivoid\libs\boost_1_54_0\boost\detail\iterator.hpp(83) : see reference to class template instantiation 'std::iterator_traits<_Iter>' being compiled 1> with 1> [ 1> _Iter=boost::range_detail::any_iterator<IFooBar,boost::random_access_traversal_tag,const IFooBar &,ptrdiff_t,boost::any_iterator_buffer<64>> 1> ] 1> c:\users\voivoid\libs\boost_1_54_0\boost\iterator\iterator_traits.hpp(30) : see reference to class template instantiation 'boost::detail::iterator_traits<Iterator>' being compiled 1> with 1> [ 1> Iterator=boost::range_detail::any_iterator<IFooBar,boost::random_access_traversal_tag,const IFooBar &,ptrdiff_t,boost::any_iterator_buffer<64>> 1> ] 1> c:\users\voivoid\libs\boost_1_54_0\boost\range\iterator_range_core.hpp(141) : see reference to class template instantiation 'boost::iterator_value<Iterator>' being compiled 1> with 1> [ 1> Iterator=boost::range_detail::any_iterator<IFooBar,boost::random_access_traversal_tag,const IFooBar &,ptrdiff_t,boost::any_iterator_buffer<64>> 1> ] 1> c:\users\voivoid\libs\boost_1_54_0\boost\range\any_range.hpp(95) : see reference to class template instantiation 'boost::iterator_range<IteratorT>' being compiled 1> with 1> [ 1> IteratorT=boost::range_detail::any_iterator<IFooBar,boost::random_access_traversal_tag,const IFooBar &,ptrdiff_t,boost::any_iterator_buffer<64>> 1> ] 1> c:\users\voivoid\projects\cpptestapp\cpptestapp\main.cpp(19) : see reference to class template instantiation 'boost::range_detail::any_range<Value,Traversal,Reference,Difference>' being compiled 1> with 1> [ 1> Value=IFooBar, 1> Traversal=boost::random_access_traversal_tag, 1> Reference=const IFooBar &, 1> Difference=ptrdiff_t 1> ] Thanks. -- View this message in context: http://boost.2283326.n4.nabble.com/boost-any-range-with-an-abstract-class-re... Sent from the Boost - Users mailing list archive at Nabble.com.

Hi, voivoid wrote:
Compilation fails with the following error ( looks like any_range value is supposed to be copy-constructable? ) Is there any workaround?
I don't know the details of any_range, but here is a hack: Change Line 49-51 of <boost/range/detail/any_iterator_interface.hpp> typedef typename remove_const< typename remove_reference<Reference>::type >::type reference_as_value_type; to typedef typename mpl::if_< mpl::or_< is_abstract<typename remove_reference<Reference>::type> , is_array<typename remove_reference<Reference>::type> > , Reference , typename remove_const< typename remove_reference<Reference>::type >::type >::type reference_as_value_type; Regards, Michel P.S. When you post a thread to Boost mailing list, please include the library name (in the bracket) at the beginning of the subject. (e.g. [range] any_range with an abstract class reference) This will draw more attention to the post.
participants (2)
-
Michel Morin
-
voivoid