
Hi Steven, I recently gave a presentation about type erasure in general, and your library in particular, at our local C++ UG (see here http://prezi.com/kg6d82f-_yky/type-erasure/ or the examples at https://github.com/CppUGBerlin/Talks/tree/master/2013_02_19_TypeErasure if you are interested). During the preparation I discovered some issues I'd like to ask you about. First I think I discovered a bug either in your lib or in clang(with libc++) when compiling one of the documentation examples in C++11 mode. #include <boost/type_erasure/any.hpp> #include <boost/type_erasure/any_cast.hpp> #include <boost/type_erasure/builtin.hpp> #include <boost/type_erasure/operators.hpp> #include <boost/type_erasure/tuple.hpp> #include <iostream> namespace bte = boost::type_erasure; namespace mpl = boost::mpl; int main() { typedef bte::any< mpl::vector< bte::copy_constructible<>, bte::typeid_<>, bte::addable<>, bte::ostreamable<> > > any_type; any_type x(10); any_type y(7); any_type z(x + y); std::cout << z << std::endl; } Compiling this in C++03 mode is fine, in C++11 mode it fails with this error: In file included from te_multi03.cpp:5: ../../Staging/type_erasure/boost/type_erasure/operators.hpp:187:1: error: no matching function for call to 'call' BOOST_TYPE_ERASURE_BINARY_OPERATOR(addable, +) see [1] below for full error. The next are some things which I didn't get to work, and the documentation is silent on any pitfalls. I tried to implement Sean Parent's example from his Value Semantics talk and failed to write a concept that calls free functions instead of members. Here is what I tried (full code and error at [2] below): template<class OBJ, class T> struct drawable { static void apply(const OBJ& obj, T& os, size_t pos) { draw(obj, os, pos); } }; I get an error like: error call to function 'draw' that is neither visible in the template definition nor found by argument-dependent lookup I worked around this problem by defining a concept map, but that is not realy a good solution. On researching a better solution I saw that you already added the convenience macros BOOST_TYPE_ERASURE_MEMBER and BOOST_TYPE_ERASURE_FREE, but didn't have much luck with them. Is there a compileable example where they are used somewhere? Best regards Fabio **** [1] *************************************************************** [1] full error docu example: In file included from te_multi03.cpp:5: ../../Staging/type_erasure/boost/type_erasure/operators.hpp:187:1: error: no matching function for call to 'call' BOOST_TYPE_ERASURE_BINARY_OPERATOR(addable, +) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../Staging/type_erasure/boost/type_erasure/operators.hpp:166:20: note: expanded from macro 'BOOST_TYPE_ERASURE_BINARY_OPERATOR' return ::boost::type_erasure::call(name<T, U, R>(), lhs, rhs); \ ^~~~~~~~~~~~~~~~~~~~~~~~~~~ te_multi03.cpp:25:17: note: in instantiation of member function 'boost::type_erasure::operator+' requested here any_type z(x + y); ^ ../../Staging/type_erasure/boost/type_erasure/call.hpp:323:1: note: candidate template ignored: failed template argument deduction call( ^ ../../Staging/type_erasure/boost/type_erasure/call.hpp:356:1: note: candidate template ignored: substitution failure [with Op = boost::type_erasure::addable<boost::type_erasure::_self, boost::type_erasure::_self, boost::type_erasure::_self>, U = <const boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, boost::type_erasure::typeid_<boost::type_erasure::_self>, boost::type_erasure::addable<boost::type_erasure::_self, boost::type_erasure::_self, boost::type_erasure::_self>, boost::type_erasure::ostreamable<std::__1::basic_ostream<char>, boost::type_erasure::_self>, 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>, boost::type_erasure::_self>, boost::type_erasure::param<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, boost::type_erasure::typeid_<boost::type_erasure::_self>, boost::type_erasure::addable<boost::type_erasure::_self, boost::type_erasure::_self, boost::type_erasure::_self>, boost::type_erasure::ostreamable<std::__1::basic_ostream<char>, boost::type_erasure::_self>, 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>, const boost::type_erasure::_self &>>]: no type named 'type' in 'boost::type_erasure::detail::call_result<boost::type_erasure::addable<boost::type_erasure::_self, boost::type_erasure::_self, boost::type_erasure::_self>, void (const boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, boost::type_erasure::typeid_<boost::type_erasure::_self>, boost::type_erasure::addable<boost::type_erasure::_self, boost::type_erasure::_self, boost::type_erasure::_self>, boost::type_erasure::ostreamable<std::__1::basic_ostream<char>, boost::type_erasure::_self>, 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>, boost::type_erasure::_self> &, boost::type_erasure::param<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, boost::type_erasure::typeid_<boost::type_erasure::_self>, boost::type_erasure::addable<boost::type_erasure::_self, boost::type_erasure::_self, boost::type_erasure::_self>, boost::type_erasure::ostreamable<std::__1::basic_ostream<char>, boost::type_erasure::_self>, 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>, const boost::type_erasure::_self &> &), void>' call( ^ 1 error generated. **** [2] *************************************************************** [2] Code and error for Value semantic example: #include <boost/type_erasure/any.hpp> #include <boost/type_erasure/concept_interface.hpp> #include <boost/type_erasure/rebind_any.hpp> #include <boost/type_erasure/free.hpp> #include <vector> namespace bte = boost::type_erasure; namespace mpl = boost::mpl; //-------------------------------------------------------------------------------------------------- template<class OBJ, class T> struct drawable { static void apply(const OBJ& obj, T& os, size_t pos) { draw(obj, os, pos); } }; namespace boost { namespace type_erasure { template<class OBJ, class T, class Base> struct concept_interface< ::drawable<OBJ, T>, Base, OBJ> : Base { void draw(typename rebind_any<Base, T&>::type os, size_t pos) const { call(::drawable<OBJ, T>(), *this, os, pos); } }; } } using object_t = bte::any< mpl::vector< bte::copy_constructible<>, drawable<bte::_self, std::ostream> >>; //-------------------------------------------------------------------------------------------------- void draw(const int& value, std::ostream& out, size_t position) { out << std::string(position, ' ') << "int = " << value << std::endl; } void draw(const std::string& value, std::ostream& out, size_t position) { out << std::string(position, ' ') << "string = " << value << std::endl; } struct my_class_t {}; void draw(const my_class_t&, std::ostream& out, size_t position) { out << std::string(position, ' ') << "my_class_t" << std::endl; } //-------------------------------------------------------------------------------------------------- using document_t = std::vector<object_t>; // or std::vector<copy_on_write<object_t>>; void draw(const document_t& x, std::ostream& out, size_t position) { out << std::string(position, ' ') << "<document>" << std::endl; for (auto& e : x) { e.draw(out, position + 2); } out << std::string(position, ' ') << "</document>" << std::endl; } //-------------------------------------------------------------------------------------------------- using history_t = std::vector<document_t>; void commit(history_t& x) { assert(x.size()); x.push_back(x.back()); } void undo(history_t& x) { assert(x.size()); x.pop_back(); } document_t& current(history_t& x) { assert(x.size()); return x.back(); } //-------------------------------------------------------------------------------------------------- int main () { history_t h(1); current(h).emplace_back(0); current(h).emplace_back(std::string("Hello!")); draw(current(h), std::cout, 0); std::cout << "--------------------------" << std::endl; commit(h); current(h).emplace_back(current(h)); current(h).emplace_back(my_class_t()); draw(current(h), std::cout, 0); std::cout << "--------------------------" << std::endl; undo(h); draw(current(h), std::cout, 0); } **** Error: ************************************************************ te_sp_copy.cpp:14:59: error: call to function 'draw' that is neither visible in the template definition nor found by argument-dependent lookup static void apply(const OBJ& obj, T& os, size_t pos) { draw(obj, os, pos); } ^ ../../Staging/type_erasure/boost/type_erasure/detail/instantiate.hpp:91:28: note: in instantiation of member function 'drawable<int, std::__1::basic_ostream<char> >::apply' requested here BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_INSTANTIATE_IMPL, concept_sequence) ^ /usr/local/include/boost/preprocessor/repetition/repeat.hpp:38:60: note: expanded from macro 'BOOST_PP_REPEAT_1' # define BOOST_PP_REPEAT_1(c, m, d) BOOST_PP_REPEAT_1_I(c, m, d) ^ /usr/local/include/boost/preprocessor/repetition/repeat.hpp:43:63: note: expanded from macro 'BOOST_PP_REPEAT_1_I' # define BOOST_PP_REPEAT_1_I(c, m, d) BOOST_PP_REPEAT_1_ ## c(m, d) ^ /usr/local/include/boost/preprocessor/repetition/repeat.hpp:54:62: note: expanded from macro 'BOOST_PP_REPEAT_1_3' # define BOOST_PP_REPEAT_1_3(m, d) BOOST_PP_REPEAT_1_2(m, d) m(2, 2, d) ^ ../../Staging/type_erasure/boost/type_erasure/detail/instantiate.hpp:70:47: note: expanded from macro 'BOOST_TYPE_ERASURE_INSTANTIATE_IMPL' (void)&::boost::mpl::at_c<data, n>::type::apply; ^ ../../Staging/type_erasure/boost/type_erasure/any.hpp:182:13: note: in instantiation of function template specialization 'boost::type_erasure::detail::instantiate_concept3::apply<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::mpl::map1<boost::mpl::pair<boost::type_erasure::_self, int> > >' requested here BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U), ^ ../../Staging/type_erasure/boost/type_erasure/detail/instantiate.hpp:51:14: note: expanded from macro 'BOOST_TYPE_ERASURE_INSTANTIATE1' >::type::apply( \ ^ /usr/bin/../lib/c++/v1/memory:1681:31: note: in instantiation of function template specialization 'boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>::any<int>' requested here ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...); ^ /usr/bin/../lib/c++/v1/memory:1608:18: note: in instantiation of function template specialization 'std::__1::allocator<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>
::construct<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>, int>' requested here {__a.construct(__p, _VSTD::forward<_Args>(__args)...);} ^ /usr/bin/../lib/c++/v1/memory:1492:14: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self> >
::__construct<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>, int>' requested here {__construct(__has_construct<allocator_type, pointer, _Args...>(), ^ /usr/bin/../lib/c++/v1/vector:1519:25: note: in instantiation of function template specialization
::construct<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>, int>' requested here __alloc_traits::construct(this->__alloc(), ^ te_sp_copy.cpp:71:15: note: in instantiation of function template specialization 'std::__1::vector<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>, std::__1::allocator<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self> > >::emplace_back<int>' requested here current(h).emplace_back(0); ^ te_sp_copy.cpp:33:6: note: 'draw' should be declared prior to the call site void draw(const int& value, std::ostream& out, size_t position) { ^ te_sp_copy.cpp:14:59: error: call to function 'draw' that is neither visible in the template definition nor found by argument-dependent lookup static void apply(const OBJ& obj, T& os, size_t pos) { draw(obj, os,
'std::__1::allocator_traits<std::__1::allocator<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self> > pos); } ^ ../../Staging/type_erasure/boost/type_erasure/detail/instantiate.hpp:91:28: note: in instantiation of member function 'drawable<std::__1::basic_string<char>, std::__1::basic_ostream<char>
::apply' requested here BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_INSTANTIATE_IMPL, concept_sequence) ^ /usr/local/include/boost/preprocessor/repetition/repeat.hpp:38:60: note: expanded from macro 'BOOST_PP_REPEAT_1' # define BOOST_PP_REPEAT_1(c, m, d) BOOST_PP_REPEAT_1_I(c, m, d) ^ /usr/local/include/boost/preprocessor/repetition/repeat.hpp:43:63: note: expanded from macro 'BOOST_PP_REPEAT_1_I' # define BOOST_PP_REPEAT_1_I(c, m, d) BOOST_PP_REPEAT_1_ ## c(m, d) ^ /usr/local/include/boost/preprocessor/repetition/repeat.hpp:54:62: note: expanded from macro 'BOOST_PP_REPEAT_1_3' # define BOOST_PP_REPEAT_1_3(m, d) BOOST_PP_REPEAT_1_2(m, d) m(2, 2, d) ^ ../../Staging/type_erasure/boost/type_erasure/detail/instantiate.hpp:70:47: note: expanded from macro 'BOOST_TYPE_ERASURE_INSTANTIATE_IMPL' (void)&::boost::mpl::at_c<data, n>::type::apply; ^ ../../Staging/type_erasure/boost/type_erasure/any.hpp:182:13: note: in instantiation of function template specialization
'boost::type_erasure::detail::instantiate_concept3::apply<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::mpl::map1<boost::mpl::pair<boost::type_erasure::_self, std::__1::basic_string<char> > > >' requested here BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U), ^ ../../Staging/type_erasure/boost/type_erasure/detail/instantiate.hpp:51:14: note: expanded from macro 'BOOST_TYPE_ERASURE_INSTANTIATE1' >::type::apply( \ ^ /usr/bin/../lib/c++/v1/memory:1681:31: note: in instantiation of function template specialization 'boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>::any<std::__1::basic_string<char> >' requested here ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...); ^ /usr/bin/../lib/c++/v1/memory:1608:18: note: in instantiation of function template specialization 'std::__1::allocator<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>
::construct<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>, std::__1::basic_string<char> >' requested here {__a.construct(__p, _VSTD::forward<_Args>(__args)...);} ^ /usr/bin/../lib/c++/v1/memory:1492:14: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self> >
::__construct<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>, std::__1::basic_string<char> >' requested here {__construct(__has_construct<allocator_type, pointer, _Args...>(), ^ /usr/bin/../lib/c++/v1/vector:1519:25: note: in instantiation of function template specialization
'std::__1::allocator_traits<std::__1::allocator<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self> >
::construct<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>, std::__1::basic_string<char> >' requested here __alloc_traits::construct(this->__alloc(), ^ te_sp_copy.cpp:72:15: note: in instantiation of function template specialization 'std::__1::vector<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self>, std::__1::allocator<boost::type_erasure::any<boost::mpl::vector<boost::type_erasure::copy_constructible<boost::type_erasure::_self>, drawable<boost::type_erasure::_self, std::__1::basic_ostream<char> >, 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>, boost::type_erasure::_self> > ::emplace_back<std::__1::basic_string<char> >' requested here current(h).emplace_back(std::string("Hello!")); ^ te_sp_copy.cpp:37:6: note: 'draw' should be declared prior to the call site void draw(const std::string& value, std::ostream& out, size_t position) { ^ 2 errors generated.