[tr1] tuple / autoconversion problem

[ignore this line: it makes gmane stop complaining about top-posting]
------ Build started: Project: TR1TupleConversionProblem, Configuration: Debug Win32 ------ 1>Compiling... 1>stdafx.cpp 1>TR1TupleConversionProblem.cpp 1>[...]\boost_1_36_0\boost\fusion\sequence\intrinsic\begin.hpp(56) : error C2504: 'boost::fusion::extension::begin_impl<Tag>::apply<Sequence>' :
Hi! Trying to migrate existing code from boost::xxx to std::tr1::xxx using the boost::tr1 implementation for Visual Studio 2005 SP1 In the presence of some exotic autoconversion utility the the std::tr1::tuple version of my code fails on vc8. The error messages indicate that the conversion operator is not considered by the compiler. Below is code that fails to compile on vc8 if USE_TR1 is defined Do you have an idea how to fix this? Thanx, Markus ---snip--- #include <boost/tr1/memory.hpp> #ifdef USE_TR1 #include <boost/tr1/tuple.hpp> #else #include <boost/tuple/tuple.hpp> #endif #include <boost/any.hpp> #include <iostream> namespace Core { class AutoConverter { std::tr1::shared_ptr<boost::any> t_; public: AutoConverter(std::tr1::shared_ptr<boost::any> const & t) : t_(t) {} template <typename C> operator C () { try { boost::any & a = (*t_); return boost::any_cast<C>(a); } catch(boost::bad_any_cast & e) { std::cerr << "Internal conversion bug: " << "Failed to convert data holder to " << typeid(C).name() << "\n" << e.what() << std::endl; C c = C(); return c; } } }; inline AutoConverter Demo() { #ifdef USE_TR1 std::tr1::shared_ptr<boost::any> p_result (new boost::any(std::tr1::make_tuple(1, 2, 3, 4))); #else std::tr1::shared_ptr<boost::any> p_result (new boost::any(boost::make_tuple(1, 2, 3, 4))); #endif return p_result; } } // namespace Core int main(int argc, char* argv[]) { #ifdef USE_TR1 std::tr1::tuple<int, int, int, int> test = Core::Demo(); #else boost::tuple<int, int, int, int> test = Core::Demo(); #endif return 0; } ---snip--- Error message is: base class undefined 1> with 1> [ 1> Tag=boost::fusion::non_fusion_tag 1> ] 1> and 1> [ 1> Sequence=const Core::AutoConverter 1> ] 1> [...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp (65) : see reference to class template instantiation 'boost::fusion::result_of::begin<Sequence>' being compiled 1> with 1> [ 1> Sequence=const Core::AutoConverter 1> ] 1> [...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp (105) : see reference to function template instantiation 'boost::fusion::vector_data4<Derived,T0,T1,T2,T3> boost::fusion::vector_data4<Derived,T0,T1,T2,T3>:: init_from_sequence<Sequence>(const Sequence &)' being compiled 1> with 1> [ 1> Derived=boost::fusion::vector4<int,int,int,int>, 1> T0=int, 1> T1=int, 1> T2=int, 1> T3=int, 1> Sequence=Core::AutoConverter 1> ] 1> [...]\boost_1_36_0\boost\fusion\container\vector\vector.hpp(58) : see reference to function template instantiation 'boost::fusion::vector4<T0,T1,T2,T3>::vector4<T>(const Sequence &)' being compiled 1> with 1> [ 1> T0=int, 1> T1=int, 1> T2=int, 1> T3=int, 1> T=Core::AutoConverter, 1> Sequence=Core::AutoConverter 1> ] 1> [...]\boost_1_36_0\boost\fusion\tuple\tuple.hpp(33) : see reference to function template instantiation 'boost::fusion::vector<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>:: vector<Sequence>(const Sequence &)' being compiled 1> with 1> [ 1> T0=int, 1> T1=int, 1> T2=int, 1> T3=int, 1> T4=boost::fusion::void_, 1> T5=boost::fusion::void_, 1> T6=boost::fusion::void_, 1> T7=boost::fusion::void_, 1> T8=boost::fusion::void_, 1> T9=boost::fusion::void_, 1> Sequence=Core::AutoConverter 1> ] 1> [MYPATH]\tr1tupleconversionproblem.cpp(69) : see reference to function template instantiation 'boost::fusion::tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>:: tuple<Core::AutoConverter>(const Sequence &)' being compiled 1> with 1> [ 1> T0=int, 1> T1=int, 1> T2=int, 1> T3=int, 1> T4=boost::fusion::void_, 1> T5=boost::fusion::void_, 1> T6=boost::fusion::void_, 1> T7=boost::fusion::void_, 1> T8=boost::fusion::void_, 1> T9=boost::fusion::void_, 1> Sequence=Core::AutoConverter 1> ] 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(65) : error C2039: 'type' : is not a member of 'boost::fusion::result_of::begin<Sequence>' 1> with 1> [ 1> Sequence=const Core::AutoConverter 1> ] 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(65) : error C2146: syntax error : missing ';' before identifier 'I0' 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(65) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(65) : error C2065: 'I0' : undeclared identifier 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(66) : error C2146: syntax error : missing ';' before identifier 'i0' 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(66) : error C2065: 'i0' : undeclared identifier 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(66) : error C2893: Failed to specialize function template 'const result_of::begin<const Sequence>::type boost::fusion::begin(const Sequence &)' 1> With the following template arguments: 1> 'Core::AutoConverter' 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(66) : error C2893: Failed to specialize function template 'const result_of::begin<Sequence>::type boost::fusion::begin(Sequence &)' 1> With the following template arguments: 1> 'const Core::AutoConverter' 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(67) : error C2955: 'boost::fusion::result_of::next' : use of class template requires template argument list 1> [...]\boost_1_36_0\boost\fusion\iterator\next.hpp(50) : see declaration of 'boost::fusion::result_of::next' 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(67) : error C2039: 'type' : is not a member of 'boost::fusion::result_of::next' 1> [...]\boost_1_36_0\boost\fusion\iterator\next.hpp(50) : see declaration of 'boost::fusion::result_of::next' 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(67) : error C2039: 'type' : is not a member of 'boost::fusion::result_of::next<Iterator>' 1> with 1> [ 1> Iterator=I1 1> ] 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(67) : error C2893: Failed to specialize function template 'const result_of::next<Iterator>::type boost::fusion::next(const Iterator &)' 1> With the following template arguments: 1> 'I1' 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(67) : error C2039: 'type' : is not a member of 'boost::fusion::result_of::next<Iterator>' 1> with 1> [ 1> Iterator=I1 1> ] 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(67) : error C2893: Failed to specialize function template 'const result_of::next<Iterator>::type boost::fusion::next(const Iterator &)' 1> With the following template arguments: 1> 'I2' 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(68) : error C2100: illegal indirection 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(68) : error C2100: illegal indirection 1>[...]\boost_1_36_0\boost\fusion\container\vector\detail\vector_n.hpp(68) : error C2100: illegal indirection

Markus Werle wrote:
[ignore this line: it makes gmane stop complaining about top-posting]
Hi!
Trying to migrate existing code from boost::xxx to std::tr1::xxx using the boost::tr1 implementation for Visual Studio 2005 SP1 In the presence of some exotic autoconversion utility the the std::tr1::tuple version of my code fails on vc8. The error messages indicate that the conversion operator is not considered by the compiler.
You caught a bug. It's fixed now in SVN trunk. Thanks! Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman <joel <at> boost-consulting.com> writes:
Markus Werle wrote:
[ignore this line: it makes gmane stop complaining about top-posting]
Hi!
Trying to migrate existing code from boost::xxx to std::tr1::xxx using the boost::tr1 implementation for Visual Studio 2005 SP1 In the presence of some exotic autoconversion utility the the std::tr1::tuple version of my code fails on vc8. The error messages indicate that the conversion operator is not considered by the compiler.
You caught a bug. It's fixed now in SVN trunk. Thanks!
Wow! 40 minutes from report to fix is another PRO for OpenSource. Thanks! And now: although fixed for trunk, I am behind a firewall here, so I'd like to patch 1_36_0. Could you provide the modified files here on the list or at least name them, so I can fetch them via web-frontend? best regards, Markus

Markus Werle wrote:
Joel de Guzman <joel <at> boost-consulting.com> writes:
Markus Werle wrote:
[ignore this line: it makes gmane stop complaining about top-posting] Hi!
Trying to migrate existing code from boost::xxx to std::tr1::xxx using the boost::tr1 implementation for Visual Studio 2005 SP1 In the presence of some exotic autoconversion utility the the std::tr1::tuple version of my code fails on vc8. The error messages indicate that the conversion operator is not considered by the compiler. You caught a bug. It's fixed now in SVN trunk. Thanks!
Wow! 40 minutes from report to fix is another PRO for OpenSource. Thanks!
And now: although fixed for trunk, I am behind a firewall here, so I'd like to patch 1_36_0. Could you provide the modified files here on the list or at least name them, so I can fetch them via web-frontend?
boost/fusion/tuple/tuple.hpp boost/fusion/tuple/detail/tuple_expand.hpp I also added your test to the test suite: libs/fusion/test/sequence/tr1_tuple_auto_conv.cpp plus updated the test Jamfile Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman <joel <at> boost-consulting.com> writes:
boost/fusion/tuple/tuple.hpp boost/fusion/tuple/detail/tuple_expand.hpp
I still get compiler errors in tuple.hpp due to misssing return type in line 57: template <typename U1, typename U2> tuple & // THIS LINE IS MISSING <----------------------- operator=(std::pair<U1, U2> const& rhs) { base_type::operator=(rhs); return *this; } Very nice compiler you have ;-P. Markus

Markus Werle wrote:
Joel de Guzman <joel <at> boost-consulting.com> writes:
boost/fusion/tuple/tuple.hpp boost/fusion/tuple/detail/tuple_expand.hpp
I still get compiler errors in tuple.hpp due to misssing return type in line 57:
template <typename U1, typename U2> tuple & // THIS LINE IS MISSING <----------------------- operator=(std::pair<U1, U2> const& rhs) { base_type::operator=(rhs); return *this; }
Very nice compiler you have ;-P.
Ooops, sorry. That was hastily added. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Markus Werle wrote:
[ignore this line: it makes gmane stop complaining about top-posting]
Hi!
Trying to migrate existing code from boost::xxx to std::tr1::xxx using the boost::tr1 implementation for Visual Studio 2005 SP1 In the presence of some exotic autoconversion utility the the std::tr1::tuple version of my code fails on vc8. The error messages indicate that the conversion operator is not considered by the compiler.
Below is code that fails to compile on vc8 if USE_TR1 is defined Do you have an idea how to fix this?
I confess to being stumped at present: the code compiles with VC9, GCC and Intel 10.1, but fails with VC7.1 and VC8 :-( Not sure if any fusion experts would have any ideas? John.

John Maddock wrote:
Markus Werle wrote:
[ignore this line: it makes gmane stop complaining about top-posting]
Hi!
Trying to migrate existing code from boost::xxx to std::tr1::xxx using the boost::tr1 implementation for Visual Studio 2005 SP1 In the presence of some exotic autoconversion utility the the std::tr1::tuple version of my code fails on vc8. The error messages indicate that the conversion operator is not considered by the compiler.
Below is code that fails to compile on vc8 if USE_TR1 is defined Do you have an idea how to fix this?
I confess to being stumped at present: the code compiles with VC9, GCC and Intel 10.1, but fails with VC7.1 and VC8 :-(
Not sure if any fusion experts would have any ideas?
Fixed. I admit it's a bug. The thing is, fusion tuple adopted the TR1 interface in essence plus some more extensions to take advantage of the features fusion provides beyond TR1 (e.g. iterators, algorithms, sequence compatibility, etc.). The side effect is that corner cases like this becomes problematic on some compilers. Solution: conform to TR1 to the letter. No extras. No more, no less. The downside is that some features (e.g. copy/assign from a fusion list or view) are *now disabled*. Anyway, if you want a more feature rich implementation, go for the fusion vector. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman <joel <at> boost-consulting.com> writes:
Fixed. I admit it's a bug. The thing is, fusion tuple adopted the TR1 interface in essence plus some more extensions to take advantage of the features fusion provides beyond TR1 (e.g. iterators, algorithms, sequence compatibility, etc.). The side effect is that corner cases like this becomes problematic on some compilers.
Solution: conform to TR1 to the letter. No extras. No more, no less. The downside is that some features (e.g. copy/assign from a fusion list or view) are *now disabled*. Anyway, if you want a more feature rich implementation, go for the fusion vector.
And this here fails: #include <boost/assign/list_of.hpp> #include <boost/assign/list_inserter.hpp> #include <boost/tr1/tuple.hpp> #include <list> int main(int argc, char* argv[]) { typedef std::list<std::tr1::tuple<int, std::string> > mod_list_t; static mod_list_t const l = boost::assign::tuple_list_of(1, "A")(2, "B"); return 0; } Any hint? Markus

Markus Werle wrote:
And this here fails:
#include <boost/assign/list_of.hpp> #include <boost/assign/list_inserter.hpp> #include <boost/tr1/tuple.hpp>
#include <list>
int main(int argc, char* argv[]) { typedef std::list<std::tr1::tuple<int, std::string> > mod_list_t;
static mod_list_t const l = boost::assign::tuple_list_of(1, "A")(2, "B");
return 0; }
Any hint?
I'm not familiar with boost assign. Could you please provide a test case that does not use boost.assign? Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman <joel <at> boost-consulting.com> writes:
Markus Werle wrote:
And this here fails:
#include <boost/assign/list_of.hpp> #include <boost/assign/list_inserter.hpp> #include <boost/tr1/tuple.hpp>
#include <list>
int main(int argc, char* argv[]) { typedef std::list<std::tr1::tuple<int, std::string> > mod_list_t;
static mod_list_t const l = boost::assign::tuple_list_of(1, "A")(2, "B");
return 0; }
Any hint?
I'm not familiar with boost assign. Could you please provide a test case that does not use boost.assign?
Actually I played around with boost::assign and tried to fix this myself. The problem is that boost::assign::tuple_list_of(...) returns something that is convertibel to std::list<boost::tuple<int, string> >, but not to std::list<std::tr1::::tuple<int, string> >. Is it hard work and/or useful to make this compile? ---snip---- #include <boost/tr1/tuple.hpp> #include <boost/tuple/tuple.hpp> #include <string> #include <list> int main(int argc, char* argv[]) { typedef std::list<std::tr1::tuple<int, std::string> > list_t; typedef std::list<boost::tuple<int, std::string> > b_list_t; b_list_t bl; list_t l = bl; return 0; }

Markus Werle <numerical.simulation <at> web.de> writes:
Is it hard work and/or useful to make this compile?
---snip---- #include <boost/tr1/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <string> #include <list>
int main(int argc, char* argv[]) { typedef std::list<std::tr1::tuple<int, std::string> > list_t; typedef std::list<boost::tuple<int, std::string> > b_list_t;
b_list_t bl; list_t l = bl;
return 0; }
Ooops! Now it is me copyying the wrong stuff, sorry: int main(int argc, char* argv[]) { typedef std::tr1::tuple<int, std::string> tr1_t; typedef boost::tuple<int, std::string> b_t; tr1_t t; b_t t1 = t; return 0; }

Markus Werle wrote:
Joel de Guzman <joel <at> boost-consulting.com> writes:
Markus Werle wrote:
And this here fails:
#include <boost/assign/list_of.hpp> #include <boost/assign/list_inserter.hpp> #include <boost/tr1/tuple.hpp>
#include <list>
int main(int argc, char* argv[]) { typedef std::list<std::tr1::tuple<int, std::string> > mod_list_t;
static mod_list_t const l = boost::assign::tuple_list_of(1, "A")(2, "B");
return 0; }
Any hint? I'm not familiar with boost assign. Could you please provide a test case that does not use boost.assign?
Actually I played around with boost::assign and tried to fix this myself. The problem is that boost::assign::tuple_list_of(...) returns something that is convertibel to std::list<boost::tuple<int, string> >, but not to std::list<std::tr1::::tuple<int, string> >.
Is it hard work and/or useful to make this compile?
I think you are looking at the wrong solution. The solution is to ask the boost.assign authors to support TR1 tuple. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman <joel <at> boost-consulting.com> writes:
I'm not familiar with boost assign. Could you please provide a test case that does not use boost.assign?
I made a fix proposal in http://svn.boost.org/trac/boost/ticket/2235 Markus
participants (3)
-
Joel de Guzman
-
John Maddock
-
Markus Werle