[fusion] Compile Error using BOOST_FUSION_DEFINE_STRUCT_INLINE with VC10 and GCC 4.2.1
HI, the following code gives a compile error on VC10 and GCC 4.2.1. Clang and GCC 4.7 like it: #include <boost/fusion/sequence.hpp> #include <boost/fusion/include/define_struct_inline.hpp> #include <iostream> template<class T> struct enclosing { BOOST_FUSION_DEFINE_STRUCT_INLINE( employee, (std::string, name) (int, age)) }; int main() { enclosing<int>::employee e; e.name="abc"; std::cout<<boost::fusion::deref(boost::fusion::begin(e)); } complete error mssag on VC10: 1>c:\program files (x86)\boost\boost_1_51\boost\fusion\iterator\deref.hpp(34): error C2504: 'enclosing<T>::employee::employee_iterator<boost_fusion_uglified_Seq,N>::deref<boost_fusion_uglified_T>': Basisklasse undefiniert 1> with 1> [ 1> T=int, 1> boost_fusion_uglified_Seq=enclosing<int>::employee, 1> N=0 1> ] 1> and 1> [ 1> boost_fusion_uglified_T=enclosing<int>::employee::employee_iterator<enclosing<int>::employee,0> 1> ] 1> c:\program files (x86)\boost\boost_1_51\boost\fusion\iterator\deref.hpp(53): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "boost::fusion::extension::deref_impl<boost::fusion::iterator_facade_tag>::apply<Iterator>". 1> with 1> [ 1> Iterator=enclosing<int>::employee::employee_iterator<enclosing<int>::employee,0> 1> ] 1> c:\users\ulfi\documents\visual studio 2010\projects\test\test\test.cpp(18): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "boost::fusion::result_of::deref<Iterator>". 1> with 1> [ 1> Iterator=enclosing<int>::employee::employee_iterator<enclosing<int>::employee,0> 1> ] 1>c:\users\ulfi\documents\visual studio 2010\projects\test\test\test.cpp(18): error C2893: Funktionsvorlage 'result_of::deref<Iterator>::type boost::fusion::deref(const Iterator &)' konnte nicht spezialisiert werden 1> Mit den folgenden Vorlagenargumenten: 1> 'enclosing<T>::employee::employee_iterator<boost_fusion_uglified_Seq,N>' 1> with 1> [ 1> T=int, 1> boost_fusion_uglified_Seq=enclosing<int>::employee, 1> N=0 1> ] I don't have a clue what is wrong here. Is the error on my side? i just added the template<class T> to the example code of BOOST_FUSION_DEFINE_STRUCT_INLINE. Without, everything is fine. Gretings, Oswin
the following code gives a compile error on VC10 and GCC 4.2.1. Clang and GCC 4.7 like it:
#include <boost/fusion/sequence.hpp> #include <boost/fusion/include/define_struct_inline.hpp> #include <iostream>
template<class T> struct enclosing { BOOST_FUSION_DEFINE_STRUCT_INLINE( employee, (std::string, name) (int, age)) };
int main() { enclosing<int>::employee e; e.name="abc"; std::cout<<boost::fusion::deref(boost::fusion::begin(e)); }
[snip]
I don't have a clue what is wrong here. Is the error on my side? i just added the template<class T> to the example code of BOOST_FUSION_DEFINE_STRUCT_INLINE. Without, everything is fine.
For MSVC, this is caused by a bug that seems to be triggered when a triply nested template class (i.e. a nested template class inside a nested template class inside a template class) is partially specialized. I reported the bug to Microsoft [1], but haven't heard back from them. This actually used to be a problem for BOOST_FUSION_DEFINE_TPL_STRUCT_INLINE even with a non-template enclosing class, because in my original design, the iterator class was nested inside the sequence class, so you had a triply nested template class (the iterator metafunction nested inside the iterator nested inside the sequnce). I worked around that by declaring the iterator in the same scope as the sequence, so one level of nesting was removed, but if you use a template enclosing class, you once again have a triply nested template (the iterator metafunction nested inside the iterator nested inside the enclosing class), and I don't see what I can do about *that*. GCC 4.2 seems to be suffering from a similar bug. Your example code works with GCC 4.5 and higher, and fails to compile with GCC 4.4 and lower. There's not much to do in terms of reporting this bug, since 4.4 and earlier are no longer maintained. If anyone can suggest a workaround for these compiler bugs, I am happy to implement them. Regards, Nate [1] https://connect.microsoft.com/VisualStudio/feedback/details/757891/c-compile...
Hi, thanks for the reply! On 2012-10-24 04:45, Nathan Ridge wrote:
For MSVC, this is caused by a bug that seems to be triggered when a triply nested template class (i.e. a nested template class inside a nested template class inside a template class) is partially specialized. I reported the bug to Microsoft [1], but haven't heard back from them. So this bug is known. Could a warning be added to the documentation until this is fixed? (if it is possible at all?). At last for the compilers which are officially supported by boost.
GCC 4.2 seems to be suffering from a similar bug. Your example code works with GCC 4.5 and higher, and fails to compile with GCC 4.4 and lower. There's not much to do in terms of reporting this bug, since 4.4 and earlier are no longer maintained. Good to know. So either I workaround/disable the feature on my side on VC or GCC<4.5 or we find a workaround. OK, let's try the latter first, since i honestly don't know how to to workaround it on my side ;)
If anyone can suggest a workaround for these compiler bugs, I am happy to implement them. I have tried to understand what the macro generates and maybe we can fix it by using fusion/mpl instead of partial template specialization. I don't fully understand the macro, but maybe i am not too far off, so that my solution might still work.
the need for partial template spcialization arised because basically the type/member list (A1, a1)(A2,a2)... is translated into typedef A1 t1_type; typedef A2 t2_type; ... t1_type& t1;//linked to a1 t2_type& t2;//linked to a2 ... or something very similar to it. thus you need to specialize deref to do something roughly like( i simplyfy here because i am too lazy to look up the original solution): template<int> struct deref{}; template<> struct deref<1>{ typedef t1_type& type; type call(Sequence& seq){ return seq.t1; } }; ... now think about the following: typedef boost::fusion::vector<A1&,A2&,...AN&> t_seq; t_seq t;//tied to a1...an template<int N> struct deref{ typedef result_of::at_c<t_types,N> type; type call(Sequence& seq){ return at_c<N>(seq.t); } }; could this work? Of course this is detrimental to the compil times since fusion::vector needs to be itnroduced and instantiated. However this might just be the solution used for GCC<4.5 and MSVC, in this cas "slow" is better than "compiler gives up". Gretings, Oswin
If anyone can suggest a workaround for these compiler bugs, I am happy to implement them. I have tried to understand what the macro generates and maybe we can fix it by using fusion/mpl instead of partial template specialization. I don't fully understand the macro, but maybe i am not too far off, so that my solution might still work.
the need for partial template spcialization arised because basically the type/member list (A1, a1)(A2,a2)... is translated into
typedef A1 t1_type; typedef A2 t2_type; ... t1_type& t1;//linked to a1 t2_type& t2;//linked to a2 ...
or something very similar to it.
thus you need to specialize deref to do something roughly like( i simplyfy here because i am too lazy to look up the original solution):
template<int> struct deref{}; template<> struct deref<1>{ typedef t1_type& type; type call(Sequence& seq){ return seq.t1; } }; ...
now think about the following: typedef boost::fusion::vector<A1&,A2&,...AN&> t_seq; t_seq t;//tied to a1...an template<int N> struct deref{ typedef result_of::at_c<t_types,N> type; type call(Sequence& seq){ return at_c<N>(seq.t); } };
could this work? Of course this is detrimental to the compil times since fusion::vector needs to be itnroduced and instantiated. However this might just be the solution used for GCC<4.5 and MSVC, in this cas "slow" is better than "compiler gives up".
Nice idea! I think that would work. Could you please file a Trac ticket for this with your example code? I will post a patch there once I've implemented the workaround. Regards, Nate
Done. Do you know when you might get around to fix this issue? Currently this is a show stopper for my project. Thanks for your support! Regards, Oswin On 2012-10-25 00:25, Nathan Ridge wrote:
If anyone can suggest a workaround for these compiler bugs, I am happy to implement them. I have tried to understand what the macro generates and maybe we can fix it by using fusion/mpl instead of partial template specialization. I don't fully understand the macro, but maybe i am not too far off, so that my solution might still work.
the need for partial template spcialization arised because basically the type/member list (A1, a1)(A2,a2)... is translated into
typedef A1 t1_type; typedef A2 t2_type; ... t1_type& t1;//linked to a1 t2_type& t2;//linked to a2 ...
or something very similar to it.
thus you need to specialize deref to do something roughly like( i simplyfy here because i am too lazy to look up the original solution):
template<int> struct deref{}; template<> struct deref<1>{ typedef t1_type& type; type call(Sequence& seq){ return seq.t1; } }; ...
now think about the following: typedef boost::fusion::vector<A1&,A2&,...AN&> t_seq; t_seq t;//tied to a1...an template<int N> struct deref{ typedef result_of::at_c<t_types,N> type; type call(Sequence& seq){ return at_c<N>(seq.t); } };
could this work? Of course this is detrimental to the compil times since fusion::vector needs to be itnroduced and instantiated. However this might just be the solution used for GCC<4.5 and MSVC, in this cas "slow" is better than "compiler gives up".
Nice idea! I think that would work.
Could you please file a Trac ticket for this with your example code? I will post a patch there once I've implemented the workaround.
Regards, Nate
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Do you know when you might get around to fix this issue? Currently this is a show stopper for my project.
Hopefully this weekend.
I implemented the workaround and posted a patch as an attachment to the ticket. Please try it out and let me know if it resolves the problem. Regards, Nate
Hi, thanks a lot! It will take me one or two days to check this, because i have to adapt some of my macros, too (e.g. i have a version of this macro which is used when the struct consists of references). Right now, my time schedule doesn't allow for this but i will test ASAP! Greetings, Oswin On 2012-10-29 01:08, Nathan Ridge wrote:
Do you know when you might get around to fix this issue? Currently this is a show stopper for my project.
Hopefully this weekend.
I implemented the workaround and posted a patch as an attachment to the ticket. Please try it out and let me know if it resolves the problem.
Regards, Nate
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi, the solution works fine! thanks a lot. On 2012-10-29 01:08, Nathan Ridge wrote:
Do you know when you might get around to fix this issue? Currently this is a show stopper for my project.
Hopefully this weekend.
I implemented the workaround and posted a patch as an attachment to the ticket. Please try it out and let me know if it resolves the problem.
Regards, Nate
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
the solution works fine! thanks a lot.
Great! I am not a committer but I have requested that the maintainers of Boost.Fusion commit the patch [1]. Regards, Nate [1] http://thread.gmane.org/gmane.comp.parsers.spirit.general/25204
participants (2)
-
Nathan Ridge
-
Oswin Krause