RE: [boost] [MPL] is_sequence problem

Could it be as simple as missing the namespace on the is_sqeuence<> call?
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Joel Sent: Thursday, May 05, 2005 5:46 PM To: boost@lists.boost.org Subject: [boost] [MPL] is_sequence problem
Hi,
I have a problem with this code snippet:
#include <boost/mpl/is_sequence.hpp>
int main() { using boost::mpl::int_; using boost::mpl::is_sequence; bool b = is_sequence<int_<0> >::value; }
VC7.1 complains:
C:\dev\boost\boost\mpl\aux_\begin_end_impl.hpp(35) : error C2039: 'begin' : is not a member of 'boost::mpl::int_<N>' with [ N=0 ] C:\dev\boost\boost\mpl\begin_end.hpp(35) : see reference to class template instantiation 'boost::mpl::begin_impl<Tag>::apply<Sequence>' being compiled with [ Tag=boost::mpl::begin<boost::mpl::int_<0>>::tag_, Sequence=boost::mpl::int_<0> ] C:\dev\boost\boost\mpl\is_sequence.hpp(94) : see reference to class template instantiation 'boost::mpl::begin<Sequence>' being compiled with [ Sequence=boost::mpl::int_<0> ] C:\dev\test\mpl_is_sequence.cpp(8) : see reference to class template instantiation 'boost::mpl::is_sequence<T>' being compiled with [ T=boost::mpl::int_<0> ] C:\dev\boost\boost\mpl\aux_\begin_end_impl.hpp(35) : error C2955: 'boost::mpl::begin' : use of class template requires template argument list C:\dev\boost\boost\mpl\begin_end.hpp(38) : see declaration of 'boost::mpl::begin' C:\dev\boost\boost\mpl\begin_end.hpp(35) : error C2955: 'boost::mpl::begin' : use of class template requires template argument list C:\dev\boost\boost\mpl\begin_end.hpp(38) : see declaration of 'boost::mpl::begin' C:\dev\boost\boost\mpl\is_sequence.hpp(94) : error C3203: 'begin' : class template invalid as template argument for template parameter 'T', expected a real type
Exit code: 2
Any hints? I am relying on is_sequence to return false in this case. Comeau and g++ throws up too.
Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Brian Braatz wrote:
Could it be as simple as missing the namespace on the is_sqeuence<> call?
On Behalf Of Joel
I have a problem with this code snippet:
#include <boost/mpl/is_sequence.hpp>
int main() { using boost::mpl::int_; using boost::mpl::is_sequence;
Here's the namespace ^^^^^
bool b = is_sequence<int_<0> >::value; }
Jonathan

Brian Braatz wrote:
Could it be as simple as missing the namespace on the is_sqeuence<> call?
Have you tried it? If it was, I wouldn't have bothered the list ;-) Try replacing int_<0> with int. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel wrote:
Brian Braatz wrote:
Could it be as simple as missing the namespace on the is_sqeuence<> call?
Have you tried it? If it was, I wouldn't have bothered the list ;-) Try replacing int_<0> with int.
I think the problem is the way mpl::is_sequence is implemented. It tries to detect the presence of a "tag" typedef and a "begin" typedef and concludes that a type is an mpl::sequence if it has both. I've complained a long time ago about this. I think this behavior is error prone. It's quite easy to come up with a situation where I have a type T with a "tag" and a "begin" but is not an MPL sequence. There must be a better way. MPL should not monopolize on the usage of "tag" and a "begin" in a type. Anyway, in any case, is_sequence<int_<0> >::value should never fail to compile. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

"Joel" <joel@boost-consulting.com> wrote > Joel wrote:
Brian Braatz wrote:
Could it be as simple as missing the namespace on the is_sqeuence<> call?
Have you tried it? If it was, I wouldn't have bothered the list ;-) Try replacing int_<0> with int.
I think the problem is the way mpl::is_sequence is implemented. It tries to detect the presence of a "tag" typedef and a "begin"
On VC7.1 It uses this version template< typename BOOST_MPL_AUX_NA_PARAM(T) > struct is_sequence : not_< is_same< typename begin<T>::type, void_ > > { BOOST_MPL_AUX_LAMBDA_SUPPORT(1, is_sequence, (T)) }; where begin<T>::type forwards to T::begin eg this solves the problem temporarily : : namespace boost {namespace mpl{ template<int N> struct begin<int_<N> > : void_{}; }} regards Andy Little

Joel wrote:
I think the problem is the way mpl::is_sequence is implemented. It tries to detect the presence of a "tag" typedef and a "begin" typedef and concludes that a type is an mpl::sequence if it has both. I've complained a long time ago about this.
One could argue that the problem is the existence of is_sequence.

Joel <joel@boost-consulting.com> writes:
Joel wrote:
Brian Braatz wrote:
Could it be as simple as missing the namespace on the is_sqeuence<> call? Have you tried it? If it was, I wouldn't have bothered the list ;-) Try replacing int_<0> with int.
I think the problem is the way mpl::is_sequence is implemented. It tries to detect the presence of a "tag" typedef and a "begin" typedef and concludes that a type is an mpl::sequence if it has both. I've complained a long time ago about this. I think this behavior is error prone. It's quite easy to come up with a situation where I have a type T with a "tag" and a "begin" but is not an MPL sequence. There must be a better way. MPL should not monopolize on the usage of "tag" and a "begin" in a type.
I never liked is_sequence in the first place. 1. Anything that makes structural checks is prone to masquerades like the one you cite. 2. Whenever you check if something is a sequence and do something different based on that fact, genericity is broken. We went through this discussion with boost::variant. Are you sure you want to be using even a perfect implementation of is_sequence? -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Joel <joel@boost-consulting.com> writes:
I think the problem is the way mpl::is_sequence is implemented. It tries to detect the presence of a "tag" typedef and a "begin" typedef and concludes that a type is an mpl::sequence if it has both. I've complained a long time ago about this. I think this behavior is error prone. It's quite easy to come up with a situation where I have a type T with a "tag" and a "begin" but is not an MPL sequence. There must be a better way. MPL should not monopolize on the usage of "tag" and a "begin" in a type.
I never liked is_sequence in the first place.
1. Anything that makes structural checks is prone to masquerades like the one you cite.
2. Whenever you check if something is a sequence and do something different based on that fact, genericity is broken. We went through this discussion with boost::variant.
Are you sure you want to be using even a perfect implementation of is_sequence?
I'll have to think about this question some more. Right off the bat, type categorization plus enable_if allows constrained genericity, which IMO, is a good thing. We don't really break genericity, we constrain it. That said, both you and Peter have good points. Points to ponder on some more... I wonder what Aleksey thinks about this. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman <joel@boost-consulting.com> writes: > David Abrahams wrote: >> Joel <joel@boost-consulting.com> writes: > >>>I think the problem is the way mpl::is_sequence is implemented. >>>It tries to detect the presence of a "tag" typedef and a "begin" >>>typedef and concludes that a type is an mpl::sequence if it >>>has both. I've complained a long time ago about this. I think >>>this behavior is error prone. It's quite easy to come up with >>>a situation where I have a type T with a "tag" and a "begin" >>>but is not an MPL sequence. There must be a better way. MPL >>>should not monopolize on the usage of "tag" and a "begin" >>>in a type. >> I never liked is_sequence in the first place. 1. Anything that >> makes structural checks is prone to masquerades like >> the one you cite. >> 2. Whenever you check if something is a sequence and do something >> different based on that fact, genericity is broken. We went >> through this discussion with boost::variant. >> Are you sure you want to be using even a perfect implementation of >> is_sequence? > > I'll have to think about this question some more. Right off the > bat, type categorization plus enable_if allows constrained > genericity, which IMO, is a good thing. We don't really break > genericity, we constrain it. As long as you're not using it to select between behaviors, it's OK. I'm not sure that you get better error messages by removing overloads than if you had used a nice BOOST_STATIC_ASSERT, though. -- Dave Abrahams Boost Consulting www.boost-consulting.com

"David Abrahams" <dave@boost-consulting.com> wrote
Are you sure you want to be using even a perfect implementation of is_sequence?
I'm sure one good use is giving more concise error messages. BOOST_STATIC_ASSERT((boost::mpl::is_sequence<T>::value)); (or other preferred invocation) can help to pinpoint a conceptual error (or a lack of a '::type) quickly. regards Andy Little

"Andy Little" <andy@servocomm.freeserve.co.uk> writes:
"David Abrahams" <dave@boost-consulting.com> wrote
Are you sure you want to be using even a perfect implementation of is_sequence?
I'm sure one good use is giving more concise error messages. BOOST_STATIC_ASSERT((boost::mpl::is_sequence<T>::value)); (or other preferred invocation) can help to pinpoint a conceptual error (or a lack of a '::type) quickly.
Good point. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Joel writes:
Joel wrote:
Brian Braatz wrote:
Could it be as simple as missing the namespace on the is_sqeuence<> call?
Have you tried it? If it was, I wouldn't have bothered the list ;-) Try replacing int_<0> with int.
I think the problem is the way mpl::is_sequence is implemented. It tries to detect the presence of a "tag" typedef and a "begin" typedef and concludes that a type is an mpl::sequence if it has both.
Of course it doesn't. The behavior you cite only takes place as a workaround for broken compilers (MSVC <= 7.0) -- which is quite obvious from the code.
I've complained a long time ago about this.
A link?
I think this behavior is error prone. It's quite easy to come up with a situation where I have a type T with a "tag" and a "begin" but is not an MPL sequence.
Not that I think it's an implementation that is worth defending, but in all fairness it's hard to imagine a real-world occurrence of a type with nested _typenames_ "tag" and "begin" that wasn't intended to be an MPL sequence. IOW, the workaround is a good enough real-world approximation of the real thing.
There must be a better way.
http://www.boost.org/libs/mpl/doc/refmanual/is-sequence.html#expression-sema...
Anyway, in any case, is_sequence<int_<0> >::value should never fail to compile.
Yes, it shouldn't. I'll look into it. -- Aleksey Gurtovoy MetaCommunications Engineering

Hi Aleksey, Aleksey Gurtovoy wrote:
I think the problem is the way mpl::is_sequence is implemented. It tries to detect the presence of a "tag" typedef and a "begin" typedef and concludes that a type is an mpl::sequence if it has both.
Of course it doesn't. The behavior you cite only takes place as a workaround for broken compilers (MSVC <= 7.0) -- which is quite obvious from the code.
Oh sorry :( Should've read the code more closely.
I've complained a long time ago about this.
A link?
T'was a private email. Sorry, can't find it. I'm wrong.
I think this behavior is error prone. It's quite easy to come up with a situation where I have a type T with a "tag" and a "begin" but is not an MPL sequence.
Not that I think it's an implementation that is worth defending, but in all fairness it's hard to imagine a real-world occurrence of a type with nested _typenames_ "tag" and "begin" that wasn't intended to be an MPL sequence. IOW, the workaround is a good enough real-world approximation of the real thing.
Understood.
There must be a better way.
http://www.boost.org/libs/mpl/doc/refmanual/is-sequence.html#expression-sema...
Looks good. I wasn't aware that begin<x> can return void_ when x is not a sequence.
Anyway, in any case, is_sequence<int_<0> >::value should never fail to compile.
Yes, it shouldn't. I'll look into it.
Thanks! I wonder what you have to say regarding the argument on the existence of is_sequence? Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
participants (8)
-
Aleksey Gurtovoy
-
Andy Little
-
Brian Braatz
-
David Abrahams
-
Joel
-
Joel de Guzman
-
Jonathan Turkanis
-
Peter Dimov