RE: [boost] MPL Lambda on MSVC 7
Jaap Suter wrote: > Hi, Hi Jaap, > I need some help with providing lambda support for my own > meta functions. I think this has to do with the following thread: > > http://aspn.activestate.com/ASPN/Mail/Message/1387917 > > but I can't really figure out what to do. Have you seen this one - http://lists.boost.org/MailArchives/boost/msg39533.php? That's pretty much all there is to it. > > Basically, I have the following meta function (more > complicated in real life, but the number of parameters is the same) > > template< class A, class B, class C > > struct meta_fun : mpl::plus< A, B, C > {}; > > And I use it as follows: > > template< class List, class Bar > > struct foo > { > typedef typename mpl::fold< > List, > mpl::integral_c< size_t, 0 >, > meta_fun< mpl::_1, mpl::_2, Bar > > >::type type; > } > > Perhaps it is interesting to note that only the first and > second parameter of the meta function are lambda'd. The last > parameter is 'fixed' to Bar. Is this at all possible with lambda, Sure! > or do I need to 'bind' the third parameter to create a > meta-function that takes two parameters? It compiles on Intel > and GCC, so I guess it is supported. Everything that seems intuitive is supported :). If it doesn't work, it's most probably a bug. But the above example _does_ compile on every platform MPL supports - including MSVC 6.5/7.0 (assuming the latest CVS sources). Or are you using the 1.29.0 archive? > > In my actual code I'm not using mpl::plus but another meta-function > that tries to acces A::value_type and B::value_type. This works > fine on Intel and GCC, but MSVC gets the wrong types for A and B > because it tells me that: > > error C2039: 'value_type' : is not a member of > 'boost::mpl::arg' > with > [ > N=2 > ] > > This is wrong because at the point where the error occurs I'm asking > for the value_type member of something should be integral_c<> and not > arg<>. I guess the fix lies in the BOOST_MPL_AUX_LAMBDA_SUPPORT and > VOID_SPEC macros. The former one is enough. > But I don't really understand what these macros do (looking at their definitions > didn't really help either). I've tried something like: > > template< class A, class B, class C > > struct meta_fun : mpl::plus< A, B, C > > { > BOOST_MPL_AUX_LAMBDA_SUPPORT( 3, meta_fun, (A, B, C) ); > }; That's exactly how a metafunction should be patched to become usable in lambda expressions on deficient compilers (except for the semicolon at the end of the macro). > but that didn't fix it. Hmm, works for me, even if I remove the 'plus' inheritance: template< class A, class B, class C > struct meta_fun { typedef A type; BOOST_MPL_AUX_LAMBDA_SUPPORT( 3, meta_fun, (A, B, C) ) }; > I guess my question is: how would you define meta_fun so it supports > lambda on MSVC 7? I hope that all the above answers this question. > Or if it's possible, do you have some time to give a short explanation > on the LAMBDA macros, BOOST_MPL_AUX_LAMBDA_SUPPORT(arity, name, params) arity - metafunction's arity name - metafunction's name params - metafunction's formal template parameters, passed as PP tuple, e.g. '(T1,T2,T3)' > what compiler-problems they try to fix, and how they do it? > They are compensating the lack of partial template specialization or/and template template parameters support by the means of introducing an intrusive metafunction's introspection mechanism. The implementation details are gloriously nasty, vary from compiler to compiler, and generally aren't worth one's time. > Any information will of course be updated in the Effective MPL wiki. That would be very much appreciated! Aleksey ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Function Type Typedefs in Classes, Etc.
- Original Message - From: "Paul Mensonides" <[EMAIL PROTECTED]> > Actually, this works too: So does this: template struct is_ptr_to_mem_fun { enum { value = false }; }; template struct is_ptr_to_mem_fun { private: template static char check(const U O::*); template static char (& check(...))[2]; public: enum { value = sizeof(check(0)) != 1 }; }; Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] MPL Lambda on MSVC 7
Hi, I need some help with providing lambda support for my own meta functions. I think this has to do with the following thread: http://aspn.activestate.com/ASPN/Mail/Message/1387917 but I can't really figure out what to do. Basically, I have the following meta function (more complicated in real life, but the number of parameters is the same) template< class A, class B, class C > struct meta_fun : mpl::plus< A, B, C > {}; And I use it as follows: template< class List, class Bar > struct foo { typedef typename mpl::fold< List, mpl::integral_c< size_t, 0 >, meta_fun< mpl::_1, mpl::_2, Bar > >::type type; } Perhaps it is interesting to note that only the first and second parameter of the meta function are lambda'd. The last parameter is 'fixed' to Bar. Is this at all possible with lambda, or do I need to 'bind' the third parameter to create a meta-function that takes two parameters? It compiles on Intel and GCC, so I guess it is supported. In my actual code I'm not using mpl::plus but another meta-function that tries to acces A::value_type and B::value_type. This works fine on Intel and GCC, but MSVC gets the wrong types for A and B because it tells me that: error C2039: 'value_type' : is not a member of 'boost::mpl::arg' with [ N=2 ] This is wrong because at the point where the error occurs I'm asking for the value_type member of something should be integral_c<> and not arg<>. I guess the fix lies in the BOOST_MPL_AUX_LAMBDA_SUPPORT and VOID_SPEC macros. But I don't really understand what these macros do (looking at their definitions didn't really help either). I've tried something like: template< class A, class B, class C > struct meta_fun : mpl::plus< A, B, C > { BOOST_MPL_AUX_LAMBDA_SUPPORT( 3, meta_fun, (A, B, C) ); }; but that didn't fix it. I guess my question is: how would you define meta_fun so it supports lambda on MSVC 7? Or if it's possible, do you have some time to give a short explanation on the LAMBDA macros, what compiler-problems they try to fix, and how they do it? Any information will of course be updated in the Effective MPL wiki. Thanks, Jaap Suter ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Function Type Typedefs in Classes, Etc.
- Original Message - From: "Paul Mensonides" <[EMAIL PROTECTED]> Actually, this works too: template struct is_ptr_to_mem_fun { enum { value = false }; }; template struct is_ptr_to_mem_fun { private: template struct helper { enum { value = false }; }; template struct helper { enum { value = true }; }; public: enum { value = helper::value }; }; The idea being that the function type (if that is what it is) is adjusted to a pointer-to-function type. Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Fun, only handled by vc6/7!
- Original Message - From: "David Abrahams" <[EMAIL PROTECTED]> > >> Here's an interesting turn-of-the-tables: I was experimenting with > >> using SFINAE to disable conversion operators, and I discovered that > >> almost every compiler except vc6/7 rejects this code: > >> > >> template struct voidify { typedef void type; }; > >> template struct Y {}; > >> struct X > >> { > >> template > >> operator Y (typename voidify::type) const { return Y(); } > >> }; > > > > Is this even legal? I.e. for a user-defined conversion operator to have any > > arguments at all? > > Look twice; the argument is void. I know, but I don't think you can derive a 'void' parameter list that way. E.g. template struct test; // not defined template struct test { }; // defined void f(void) { } int main() { test< &f >(); // error return 0; } In other words, the "void" parameter list is fundamentally different than "type void". Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Function Type Typedefs in Classes, Etc.
Is this well-formed: struct X { typedef void func_t(int); func_t member; }; void X::member(int) { return; } What about: struct X { typedef void func_t(int) const; // ^ func_t member; }; void X::member(int) const { return; } This is the root of my question: template struct test; template struct test { typedef R type; }; struct X { }; test< void (X::*)(int) >::type // what type is this? Is it a function type, or is it a "member function type"? The reason I ask is I'm trying to make a 'is_ptr_to_mem_fun' traits class without massive specialization. This works on Comeau C++: template struct is_ptr_to_mem_fun { enum { value = false }; }; template struct is_ptr_to_mem_fun { private: template static char check(U (*)[1]); template static char (& check(...))[2]; public: enum { value = sizeof(check(0)) != 1 }; }; struct X { }; int main() { std::cout << is_ptr_to_mem_fun< int X::* >::value << ' ' << is_ptr_to_mem_fun< int (X::*)(void) >::value << &std::endl; return 0; } ??? Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Fun, only handled by vc6/7!
"Paul Mensonides" <[EMAIL PROTECTED]> writes: > - Original Message - > From: "David Abrahams" <[EMAIL PROTECTED]> > To: "boost" <[EMAIL PROTECTED]> > Sent: Saturday, January 11, 2003 8:10 PM > Subject: [boost] Fun, only handled by vc6/7! > > >> >> Here's an interesting turn-of-the-tables: I was experimenting with >> using SFINAE to disable conversion operators, and I discovered that >> almost every compiler except vc6/7 rejects this code: >> >> template struct voidify { typedef void type; }; >> template struct Y {}; >> struct X >> { >> template >> operator Y (typename voidify::type) const { return Y(); } >> }; > > Is this even legal? I.e. for a user-defined conversion operator to have any > arguments at all? Look twice; the argument is void. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Fun, only handled by vc6/7!
Here's an interesting turn-of-the-tables: I was experimenting with using SFINAE to disable conversion operators, and I discovered that almost every compiler except vc6/7 rejects this code: template struct voidify { typedef void type; }; template struct Y {}; struct X { template operator Y (typename voidify::type) const { return Y(); } }; int main() { X x; return 0; } You can substitute enable_if for voidify to see why I care; this is just a minimal example. Note that many of the same compilers will accept voidify::type as the argument, though! -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
- Original Message - From: "David Abrahams" <[EMAIL PROTECTED]> > > I guess it would depend heavily on the compiler used. For instance, a > > compiler might not actually create the storage at all unless the address of > > the static const is actually needed--which would cause the effect to be > > minimal. On the other hand, unless you mapped all the enumerators of a > > particular value to the same type, you'd have issues with name lookup. > > My proposal with integral_c would do exactly that. Yes, and I like it. ;) The only thing I don't like about it is the potential interplay with the rest of the type system. The mapping to a single type per value is good, but it doesn't completely solve the problem. I just think it is better to steer clear of the situation altogether. I personally only use static const for interface values though and use enumerations for internal values (with casting if necessary). Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
"Paul Mensonides" <[EMAIL PROTECTED]> writes: > - Original Message - > From: "David Abrahams" <[EMAIL PROTECTED]> > > >> "Paul Mensonides" <[EMAIL PROTECTED]> writes: >> >> >> > Well, yes. If you do that, however, it removes one of the primary >> > reasons >> >> > to use enumerations, which is for the syntactic convenience. The > only >> >> > reason left to use enums is to avoid the static storage of the >> >> > values. >> >> >> >> And to improve compilation and linking speed. >> >> I haven't done the tests of course, but I'd expect it to be faster >> anyway. Allocating space in the link map for the static constant and >> resolving it across translation units has to cost something. > > I guess it would depend heavily on the compiler used. For instance, a > compiler might not actually create the storage at all unless the address of > the static const is actually needed--which would cause the effect to be > minimal. On the other hand, unless you mapped all the enumerators of a > particular value to the same type, you'd have issues with name lookup. My proposal with integral_c would do exactly that. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
- Original Message - From: "David Abrahams" <[EMAIL PROTECTED]> > "Paul Mensonides" <[EMAIL PROTECTED]> writes: > > >> > Well, yes. If you do that, however, it removes one of the primary > > reasons > >> > to use enumerations, which is for the syntactic convenience. The only > >> > reason left to use enums is to avoid the static storage of the > >> > values. > >> > >> And to improve compilation and linking speed. > > I haven't done the tests of course, but I'd expect it to be faster > anyway. Allocating space in the link map for the static constant and > resolving it across translation units has to cost something. I guess it would depend heavily on the compiler used. For instance, a compiler might not actually create the storage at all unless the address of the static const is actually needed--which would cause the effect to be minimal. On the other hand, unless you mapped all the enumerators of a particular value to the same type, you'd have issues with name lookup. Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
"Paul Mensonides" <[EMAIL PROTECTED]> writes: >> > Well, yes. If you do that, however, it removes one of the primary > reasons >> > to use enumerations, which is for the syntactic convenience. The only >> > reason left to use enums is to avoid the static storage of the >> > values. >> >> And to improve compilation and linking speed. I haven't done the tests of course, but I'd expect it to be faster anyway. Allocating space in the link map for the static constant and resolving it across translation units has to cost something. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
- Original Message - From: "David Abrahams" <[EMAIL PROTECTED]> > >> Now Y::value and Y::value have the same type. Of course, > >> you will probably want some additional tools in integral_c, like > >> an explicit conversion to an rvalue of type T. > Misread it, sorry. > > Well, yes. If you do that, however, it removes one of the primary reasons > > to use enumerations, which is for the syntactic convenience. The only > > reason left to use enums is to avoid the static storage of the > > values. > > And to improve compilation and linking speed. Only if you never use the enumeration type itself as a function template parameter. > Not if the conversion were explicit: > > int main() { > > f( is_integer::rvalue() ); // better > > return 0; > > } > > That's what I meant all along. I like your name, 'rvalue'. ;) > > The only solution that I see is: > > > > (bool)is_integer::value && (bool)is_integer::value > > Pshaw. "Doctor, it hurts when I do this" > > so-don't-do-it-ly y'rs, It is not me that would do it. The use of enumerations--under a theoretically comforming compiler in this regard--basically tells every user of Boost what they cannot do when it shouldn't make a difference. It is, IMHO, bad for Boost to say, "you can't do this because the implementation does 'x + y' instead of 'int(x) + int(y)'". In order to safeguard Boost from this type of evil, every implementation that does any arithmetic, bitwise, and logical operations on enumeration values would have to be cast first. Likewise, this would put the cast burden on users of the library--particularly other libraries that use Boost. That is a bad policy. As I said before, though, the point is moot because compilers are so disparate in this area. At this point, we *have* to use both. Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )
- Original Message - From: "David Abrahams" <[EMAIL PROTECTED]> ... > I mean that if a metafunction is a template instead of a type you > can't treat it polymorphically with other things, e.g. you can't put > it in a type sequence. Yes, you can with the appropriate binders. That is what I meant. > > struct metafunction { > > template struct actual_metafunction { > > // ... > > }; > > }; > > > > vs. > > > > template struct metafunction { > > // ... > > }; > > mpl::lambda handles the transformation from the latter to the former. Yeah, I retract that statement. ;) It is easy to map them back and forth. > > I'm not saying the convention is bad, just that it has its own set of > > associated problems. > > > >> Other than that, the final interface you show is one that's acheivable > >> without TTP at all. > > > > Yes, you can do it without TTP, but it isn't as clean. (I only had a rough > > idea in my head when I made the remark.) You pay a price for the > > abstraction that you mention by "metafunction polymorphism." > > Hmm? Code clarity. As abstraction goes up, clarity goes down. > > Altogether, I'm quite pleased with the mechanism, as I find the linear > > typelist implementation "neat," and I've never seen anything like that > > implementation. > > libs/python/test/if_else.cpp might be of interest to you. I'll take a look. > > The template classes "fold_left" and "fold_right" are not > > even metafunctions in any normal sense. I wouldn't know what to call them! > > They're interesting to a point, but inflexible. Any given usage is > restricted to working on sequences of a particular length. Yes, however, the intended purpose is as an inline definition, not as a sequence type, and it doesn't require the code replication necessary to support something like "mpl::vector". I'm not saying that it's "super great" overall. I'm merely saying that it amuses me, and I like it. ;) Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
"Paul Mensonides" <[EMAIL PROTECTED]> writes: > - Original Message - > From: "David Abrahams" <[EMAIL PROTECTED]> > >> > solution: >> > >> > There is no non-intrusive solution. It must be cast at the call site to > a >> > common type (such as 'int' or 'bool') in order to avoid replicated > template >> > instantiation. >> > >> > */ >> >> Of course, you can use the first solution with enums as well: >> >> template >> struct integral_c >> { >>enum value_type { value = N; }; >> }; >> >> template struct Y >>: integral_c {}; >> >> >> Now Y::value and Y::value have the same type. Of course, >> you will probably want some additional tools in integral_c, like >> an explicit conversion to an rvalue of type T. > Well, yes. If you do that, however, it removes one of the primary reasons > to use enumerations, which is for the syntactic convenience. The only > reason left to use enums is to avoid the static storage of the > values. And to improve compilation and linking speed. > The automatic rvalue conversion would be nice, but you'd still get > the template instantiation problem if you did this: > > template void f(const T&); > > template class is_integer : integral_c { }; > template<> class is_integer : integral_c { }; > > template void f(const T&); > > int main() { > f( is_integer() ); // 'T' == 'is_integer' > return 0; > } Not if the conversion were explicit: f( is_integer::get() ); > What you need is both 'value' and 'rvalue': > > template struct integral_c { > enum value_type { value = V }; > static inline T rvalue() { > return value; > } > }; > > int main() { > f( is_integer::rvalue() ); // better > return 0; > } That's what I meant all along. I like your name, 'rvalue'. > This still doesn't solve one other issue though: > > template T operator && (T, T); // etc. > > ...which is evil, I agree, but possible. This can still break any > arithmetic or logical operations that involve enumerations: > > is_integer::value && is_integer::value // not constant > > The only solution that I see is: > > (bool)is_integer::value && (bool)is_integer::value Pshaw. "Doctor, it hurts when I do this" so-don't-do-it-ly y'rs, dave -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
- Original Message - From: "David Abrahams" <[EMAIL PROTECTED]> > > solution: > > > > There is no non-intrusive solution. It must be cast at the call site to a > > common type (such as 'int' or 'bool') in order to avoid replicated template > > instantiation. > > > > */ > > Of course, you can use the first solution with enums as well: > > template > struct integral_c > { >enum value_type { value = N; }; > }; > > template struct Y >: integral_c {}; > > > Now Y::value and Y::value have the same type. Of course, > you will probably want some additional tools in integral_c, like > an explicit conversion to an rvalue of type T. Well, yes. If you do that, however, it removes one of the primary reasons to use enumerations, which is for the syntactic convenience. The only reason left to use enums is to avoid the static storage of the values. The automatic rvalue conversion would be nice, but you'd still get the template instantiation problem if you did this: template void f(const T&); template class is_integer : integral_c { }; template<> class is_integer : integral_c { }; template void f(const T&); int main() { f( is_integer() ); // 'T' == 'is_integer' return 0; } What you need is both 'value' and 'rvalue': template struct integral_c { enum value_type { value = V }; static inline T rvalue() { return value; } }; int main() { f( is_integer::rvalue() ); // better return 0; } This still doesn't solve one other issue though: template T operator && (T, T); // etc. ...which is evil, I agree, but possible. This can still break any arithmetic or logical operations that involve enumerations: is_integer::value && is_integer::value // not constant The only solution that I see is: (bool)is_integer::value && (bool)is_integer::value Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: How to do this inwithboost--assert(typeid(T)==typeid(bool) )
"Paul Mensonides" <[EMAIL PROTECTED]> writes: > - Original Message - > From: "David Abrahams" <[EMAIL PROTECTED]> > >> >> >> AFAICT from browsing it quickly, the significance of TTP in your code >> is that you are passing templates instead of types as functions in the >> interfaces to your metafunctions, which I think is inadvisable, >> because it eventually breaks metafunction polymorphism. > > Not really. That is the purpose of various types of partial binding > constructs. The only real way to break metafunction polymorphism is to use > non-type template arguments in the the template template parameters, and not > even that will totally break it. I mean that if a metafunction is a template instead of a type you can't treat it polymorphically with other things, e.g. you can't put it in a type sequence. > Strictly not using template template parameters has its own problems > since you can't pass namespaces as arguments, etc.. This can > complicate a design real quick as you make more and more > "indirection" layers: > > struct metafunction { > template struct actual_metafunction { > // ... > }; > }; > > vs. > > template struct metafunction { > // ... > }; mpl::lambda handles the transformation from the latter to the former. > I'm not saying the convention is bad, just that it has its own set of > associated problems. > >> Other than that, the final interface you show is one that's acheivable >> without TTP at all. > > Yes, you can do it without TTP, but it isn't as clean. (I only had a rough > idea in my head when I made the remark.) You pay a price for the > abstraction that you mention by "metafunction polymorphism." Hmm? > The difference is that I prefer to do that abstraction external to > the core implementation and provide a bridge layer for common > usages. In any case, it turns out to be slightly longer anyway > because I forgot about the need for ::template when one (or all) of > the parameters a dependent. Yes, the language syntax gets in the way. > However, I was going for a general purpose "iterative OR" when I > started it, rather than just a solution to the particular problem. > I basically just had a general idea of something like this: > > contains::arg::arg::arg::value > > ...but the "::template" makes it longer: > > contains > ::template arg > ::template arg > ::template arg > ::value > > Altogether, I'm quite pleased with the mechanism, as I find the linear > typelist implementation "neat," and I've never seen anything like that > implementation. libs/python/test/if_else.cpp might be of interest to you. > The template classes "fold_left" and "fold_right" are not > even metafunctions in any normal sense. I wouldn't know what to call them! They're interesting to a point, but inflexible. Any given usage is restricted to working on sequences of a particular length. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Metaprogramming: Using static const or enum?
>From: "Gabriel Dos Reis" <[EMAIL PROTECTED]> > What I find confusing about the current rule is that it makes an > exception for integral type const static data member. I think the old > rule was less irregular. > > (Strangely enought, for long time -- since the publication of TC++PL3 > in 1997 -- I've been convinced of having read Bjarne write something > like "it is something I call a misfeature"; but now I'm perfectly > unable to locate something similar in TC++PL3 "special edition", so > either I dreamt or that text was removed. I can't tell. Probably the > former). No, I don't think you've dreamt it, because I've heard it, too. :) I think it's in D&E, but I haven't found it there, now. I think the context of the remark was that the rule makes integral types special, in that they may be initialised in-class (and not requiring an out-of-class definition), whereas you can't do the same with e.g. floating point values, or UDTs. However, searching for this on Google, I found this quote (http://www.cs.washington.edu/homes/gjb/doc/pcp3-quals/pcp3-paper.ps.gz): "Because of the "misfeature" of such declarations [static const] still requiring definitions outside of the class, Stroustrup still recommends using enums for static integral constant members (i.e., the "enum hack") [Str97, p. 249]." Maybe the "misfeature" was the fact that they may need definition, anyway? And not the fact that they may also _not_ need definition. In TC++PL, third edition, p. 249, he talks about use of static const vs enum, but presents them mostly as alternatives, and without saying anything about "misfeature". Trying to find the place of the quote in D&E, I found another interesting part (p. 90): --- Start quote --- In the meantime, I had experimented further with const in C with Classes and found that const was a useful alternative to macros for representing constants only if global consts were implicitly local to their compilation unit. Only in that case could the compiler easily deduce that their value really didn't change. Knowing that allows us to use simple consts in constant expressions and to *avoid allocating space for such constants*. [My emphasis] C did not adopt this rule. For example, in C++ we can write: const int max = 14; void f(int i) { int a[max+1]; switch(i) { case max: // ... } whereas in C, even today, we must write #define max 14 // ... because in C, consts may not be used in constant expressions. This makes consts far less useful in C than in C++ and leaves C dependent on the preprocessor while C++ programmers can use properly typed and scoped consts. --- End quote --- This is global const, not class static const, but it shows his appreciation over that they can be used in integral constant expressions. Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Metaprogramming: Using static const or enum?
- Original Message - From: "Gennaro Prota" <[EMAIL PROTECTED]> > >Incidently, an unnamed type has no linkage. > > I think the issue is a little more subtle in that a) it's names that > have or don't have linkage, not types b) a typedef allows you to give > a name, for linkage purposes, to what C++ calls an 'unnamed type', > e.g.: > >typedef struct { int n; } s; Yeah. However, this doesn't really apply to what I'm talking about with: enum { a, b, c }; Yes, for linkage purposes 'enum xyz { }' is equivalent to 'typedef enum { } xyz'. > Oops. X here has still external linkage, though of course you don't > know its "linkage name" and thus cannot refer it from another > translation unit. Yeah, my mistake. Sorry! Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
"Paul Mensonides" <[EMAIL PROTECTED]> writes: > func( Y::value ); // okay. > > // A temporary is created of type 'Y::value_type'. > // The address of that temporary is bound to > // the const& parameter of 'func'. > // 'func' is instantiated with 'T' == 'Y::value_type'. > > func( Y::value ); // okay. > > // A temporary is created of type 'Y::value_type'. > // The address of that temporary is bound to > // the const& parameter of 'func'. > // 'func' is instantiated with 'T' == 'Y::value_type', > // which is a *different* instantiation of 'func'. > // (i.e. unnecessary code bloat) > > /* > > problem: > > Usage causes template functions to be instantiated multiple times for no > reason. IMO, this is *way* worse than the storage necessary to hold the > static constants. > > solution: > > There is no non-intrusive solution. It must be cast at the call site to a > common type (such as 'int' or 'bool') in order to avoid replicated template > instantiation. > > */ Of course, you can use the first solution with enums as well: template struct integral_c { enum value_type { value = N; }; }; template struct Y : integral_c {}; Now Y::value and Y::value have the same type. Of course, you will probably want some additional tools in integral_c, like an explicit conversion to an rvalue of type T. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
- Original Message - From: "Terje Slettebø" <[EMAIL PROTECTED]> > Right, but members of anonymous namespaces does have external linkage, so > this is not an example of that. That's an advantage over the deprecated > file-scope static, which does have internal linkage, and is therefore > unusable as template parameters. > > The program you give compiles and runs without errors. Oops, my mistake. Paul Mensonides ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: is_convertible and vc7.1 final beta
"Carl Daniel" <[EMAIL PROTECTED]> writes: > "David Abrahams" <[EMAIL PROTECTED]> wrote in message > news:uvg0vjjrc.fsf@boost- >> How come I don't have build 2346? I've been on the Microsoft alpha >> program. > > Just lucky, I guess ;-) Apparently they only sent 2346 to people who'd > submitted more than 'X' bug reports via BetaPlace. Oh, so because I am still going through my direct line to their developers, I'm out in the cold :(. >> > Does this require a current boost snapshot from CVS, or will a 1.29 >> > installation suffice? (Seeing "sandbox" in the above, I'm assuming the >> > latter...) >> >> I don't know whether it works with 1.29; I was working with the >> latest. I can send you a zipped file which reproduces the problem all >> by itself. > > That would be cool. If it's a regression from 2292 (and especially if it's > a regression from VC7) they might just consider fixing it before RTM. I've already reported it, but I'll send it to you separately. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Metaprogramming: Using static const or enum?
On Sat, 11 Jan 2003 12:32:16 -0800, "Paul Mensonides" <[EMAIL PROTECTED]> wrote: >> 14.3.1/2 [quote-- >> >> A local type, a type with no linkage, an unnamed type or a type compounded >> from any of these types shall not be used as a template-argument for a >> template type-parameter. >> >> --end quote] > >Incidently, an unnamed type has no linkage. I think the issue is a little more subtle in that a) it's names that have or don't have linkage, not types b) a typedef allows you to give a name, for linkage purposes, to what C++ calls an 'unnamed type', e.g.: typedef struct { int n; } s; (Yes, I know what you are thinking now. There could be a defect about 14.3.1/2. I haven't checked the defect list though, so I don't know if it is already there) >Secondly, even if it is named, >it has internal linkage if it is member of a class with internal linkage: > >namespace { > >template struct X { >enum value_t { value = 10 }; >}; > >} > >template void f(const T& ref) { >// ... >return; >} > >int main() { >f( X::value ); // error: X::value_t has internal linkage >return 0; >} Oops. X here has still external linkage, though of course you don't know its "linkage name" and thus cannot refer it from another translation unit. Genny. ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
>From: "Paul Mensonides" <[EMAIL PROTECTED]> > > 14.3.1/2 [quote-- > > > > A local type, a type with no linkage, an unnamed type or a type compounded > > from any of these types shall not be used as a template-argument for a > > template type-parameter. > > > > --end quote] > > Incidently, an unnamed type has no linkage. Secondly, even if it is named, > it has internal linkage if it is member of a class with internal linkage: > > namespace { > > template struct X { > enum value_t { value = 10 }; > }; Right, but members of anonymous namespaces does have external linkage, so this is not an example of that. That's an advantage over the deprecated file-scope static, which does have internal linkage, and is therefore unusable as template parameters. The program you give compiles and runs without errors. Regards, Terje ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Re: is_convertible and vc7.1 final beta
"David Abrahams" <[EMAIL PROTECTED]> wrote in message news:uvg0vjjrc.fsf@boost- > How come I don't have build 2346? I've been on the Microsoft alpha > program. Just lucky, I guess ;-) Apparently they only sent 2346 to people who'd submitted more than 'X' bug reports via BetaPlace. > > > Does this require a current boost snapshot from CVS, or will a 1.29 > > installation suffice? (Seeing "sandbox" in the above, I'm assuming the > > latter...) > > I don't know whether it works with 1.29; I was working with the > latest. I can send you a zipped file which reproduces the problem all > by itself. That would be cool. If it's a regression from 2292 (and especially if it's a regression from VC7) they might just consider fixing it before RTM. -cd ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: is_convertible and vc7.1 final beta
"Carl Daniel" <[EMAIL PROTECTED]> writes: > "David Abrahams" <[EMAIL PROTECTED]> wrote in message > [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... >> >> Apparently, vc7.1 final beta fails to handle is_convertible properly >> under some circumstances. I tried searching a little bit for >> workarounds and came up empty. If anyone else would like to try, >> comment out the line which says >> >> # define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work" >> >> in $BOOST_SANDBOX/boost/iterator/iterator_adaptors.hpp, go to >> $BOOST_SANDBOX/boost/libs/iterator/test, and do: >> >>bjam -sBOOST= indirect_iterator_test >> > > Was this tested with the RC1 release (build 2346)? If not, I'll give it a > whirl tomorrow - it may be something that was broken only in build 2292. _MSC_FULL_VER == 13102292 How come I don't have build 2346? I've been on the Microsoft alpha program. > Does this require a current boost snapshot from CVS, or will a 1.29 > installation suffice? (Seeing "sandbox" in the above, I'm assuming the > latter...) I don't know whether it works with 1.29; I was working with the latest. I can send you a zipped file which reproduces the problem all by itself. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: is_convertible and vc7.1 final beta
"David Abrahams" <[EMAIL PROTECTED]> wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... > > Apparently, vc7.1 final beta fails to handle is_convertible properly > under some circumstances. I tried searching a little bit for > workarounds and came up empty. If anyone else would like to try, > comment out the line which says > > # define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work" > > in $BOOST_SANDBOX/boost/iterator/iterator_adaptors.hpp, go to > $BOOST_SANDBOX/boost/libs/iterator/test, and do: > >bjam -sBOOST= indirect_iterator_test > Was this tested with the RC1 release (build 2346)? If not, I'll give it a whirl tomorrow - it may be something that was broken only in build 2292. Does this require a current boost snapshot from CVS, or will a 1.29 installation suffice? (Seeing "sandbox" in the above, I'm assuming the latter...) -cd ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Hello MPL world!
Greg Colvin <[EMAIL PROTECTED]> writes: > Perhaps more progress would be made if the quest for > the "one best example" is dropped in favor of a small > series of examples? We'll need those also. But we want to figure out which one to start with. -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Hello MPL world!
Perhaps more progress would be made if the quest for the "one best example" is dropped in favor of a small series of examples? ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] is_convertible and vc7.1 final beta
Apparently, vc7.1 final beta fails to handle is_convertible properly under some circumstances. I tried searching a little bit for workarounds and came up empty. If anyone else would like to try, comment out the line which says # define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work" in $BOOST_SANDBOX/boost/iterator/iterator_adaptors.hpp, go to $BOOST_SANDBOX/boost/libs/iterator/test, and do: bjam -sBOOST= indirect_iterator_test -Dave -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Re: Hello MPL world!
On Saturday, January 11, 2003, at 01:17 PM, David B. Held wrote: "Howard Hinnant" <[EMAIL PROTECTED]> wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... [...] Despite the fact that I suggested it, I don't find it a killer example. ;-) I already code stuff like this, with this other pattern: [...] The fact that the concept is familiar to you already works in its favor, just as the familiarity of "Hello, world" is its primary feature. It provides an entry point for people not necessarily exposed to metaprogramming. Just seeing PTS spelled as "mpl::if_" might produce an "Aha!" in people checking out MPL, just like Hello, World does for a new language. Well then here's a little toy container that switches between heap-based and stack-based depending upon the fixed size length. Maybe has enough guts to spark interest, but not so much that it is too big to take in at a glance? template class stack_based { protected: static unsigned int const size = N; T data_[N]; stack_based() {} private: stack_based(const stack_based& x); }; template class heap_based { protected: static unsigned int const size = N; T* data_; heap_based() : data_(new T[size]){} ~heap_based() {delete [] data_;} heap_based& operator=(const heap_based& x) {std::copy(x.data_, x.data_ + size, data_); return *this;} private: heap_based(const heap_based& x); }; template class MyContainer : private if_, heap_based >::type { typedef typename if_, heap_based >::type base; public: using base::size; // construct MyContainer() {} MyContainer(const MyContainer& x) {std::copy(x.data_, x.data_ + size, base::data_);} T& operator[](unsigned int i) {return base::data_[i];} const T& operator[](unsigned int i) const {return base::data_[i];} typedef T* iterator; typedef const T* const_iterator; iterator begin() {return base::data_;} iterator end() {return base::data_ + size;} const_iterator begin() const {return base::data_;} const_iterator end() const {return base::data_ + size;} }; -Howard ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: And now the fun really begins
Sorry, clearly sent to wrong newsgroup :¬ ( Moral: look before you post AlisdairM ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Next revision of boost::thread
"William E. Kempf" wrote: [...] > > There is some chance you might talk me into accepting two flavors of > > threading for the Standard - full threads and threads-lite in effect. > > But picking and choosing between four or five optional thread features > > leaves me cold. > > I can understand that, but my hands are somewhat tied by POSIX, whose > standards bodies took the opposite stance on this issue. It seems to me that you're missing the purpose/role of The Single UNIX Specification and various "Product Standards" within the UNIX branding/ certification program of The Open Group consortium: e.g. UNIX 95, UNIX 98 Workstation, UNIX 98 Server, etc.]. Well, < note that this is rather old SUSv2-stuff. The current version is SUSv3[/TC1](*) > http://www.unix-systems.org/version2/whatsnew/threadspaper.pdf (Threads and the Single UNIX(R) Specification, Version 2) For conformance to the Single UNIX Specification, Version 2, the threads options are split so that non-realtime functionality is mandatory, and realtime functionality is grouped into a single option: the Realtime Threads Feature Group. regards, alexander. (*) http://www.unix-systems.org http://www.opengroup.org/austin ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Hello MPL world!
On Saturday, January 11, 2003, at 09:42 AM, Beman Dawes wrote: >Or maybe even just: > > template > struct my_container > : if_::value, impl1, impl2>::type > { > ... > }; These are the examples that resonate with me, particularly Howard's version. It looks so easy, and has obvious practical uses. It would motivate me. But it needs to be a complete, compilable, runable, program so I can try it, modify it, etc. Despite the fact that I suggested it, I don't find it a killer example. ;-) I already code stuff like this, with this other pattern: template struct impl; template struct impl { }; // impl1, optimized template struct impl { }; // impl2, not optimized template struct my_container : private impl::value> { ... }; I'm not convinced that the version using if_ is significantly simpler. :-\ template struct impl1 { }; // optimized template struct impl2 { }; // not optimized template struct my_container : private if_, impl1, impl2 >::type { ... }; if_ really shines when it is inconvenient to partially specialize an entire class just to get one little different type: template struct some_example { typedef typename if_::value, type1, type2>::type the_type; ... }; Good example: http://www.cuj.com/experts/1901/austern.htm?topic=experts -Howard ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] And now the fun really begins
Looking at integrating Orpheus with our BCB code now we are upgraded to BCB6. Timing really sucks :¬ ( Anyone else here working out TurboPower support this week? Particularly sad will be if we can't get a BCB6 version of SleuthQA, it was invaluble to us with BCB5 Here's hoping the TurboPower staff are having a better time of it over there. -- AlisdairM Team Thai Kingdom ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Metaprogramming: Using static const or enum?
Gennaro Prota <[EMAIL PROTECTED]> writes: | On 09 Jan 2003 18:02:51 +0100, Gabriel Dos Reis | <[EMAIL PROTECTED]> wrote: | | >So you propose that the presence/absence of an initializer turns an | >expression designating a static data member into an rvalue or lvalue? | > | >I can't speak for the committee. Personnally, I do know that that | >proposal won't get my support. I believe the lvalue/rvalue thingy is | >already confused enought to add such a fragile, more confusing, | >non-uniform rule to the language. | | Well, mine was just a "compromise" proposal :-) If it was up to me I | would have just made them rvalues. Isn't the current rule about the | need of a definition more confusing than that? What I find confusing about the current rule is that it makes an exception for integral type const static data member. I think the old rule was less irregular. (Strangely enought, for long time -- since the publication of TC++PL3 in 1997 -- I've been convinced of having read Bjarne write something like "it is something I call a misfeature"; but now I'm perfectly unable to locate something similar in TC++PL3 "special edition", so either I dreamt or that text was removed. I can't tell. Probably the former). -- Gaby ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Metaprogramming: Using static const or enum?
"Paul Mensonides" <[EMAIL PROTECTED]> writes: [...] | However, this | raises another interesting problem. Many enumerations used for this purpose | are unnamed: | | template struct is_ptr { | enum { value = false }; | }; | | template struct is_ptr { | enum { value = true }; | }; | | This has its own problem in the same templated "pass by reference" | situation. Namely, a template type argument cannot refer to an unnamed | type: | | template T func(const T& ref) { | return ref; | } | | int main() { | func( is_ptr::value ); | // error: argument deduction yields unnamed type Probably I'm being dense here, but please could you work out *why* you think the above should fail? -- Gaby ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Hello MPL world!
Howard Hinnant <[EMAIL PROTECTED]> writes: > On Saturday, January 11, 2003, at 09:42 AM, Beman Dawes wrote: > >> >Or maybe even just: >> > >> > template >> > struct my_container >> > : if_::value, impl1, impl2>::type >> > { >> > ... >> > }; >> >> These are the examples that resonate with me, >> particularly Howard's version. It looks so easy, and >> has obvious practical uses. It would motivate me. >> >> But it needs to be a complete, compilable, runable, >> program so I can try it, modify it, etc. > > Despite the fact that I suggested it, I don't find it a > killer example. ;-) I'm not sure we're looking for one. Is the classic "hello, world" a killer example of why traditional C++ is cool? I don't think so. On the other hand, if you've never seen C++, you can get a feeling for what it's like to work with the language from looking at "hello, world". > I already code stuff like this, with this other pattern: > I'm not convinced that the version using if_ is > significantly simpler. :-\ I don't think we're trying to beat that example by very much. The person already familiar with metaprogramming won't find much to be impressed with, unless they look very closely, in which case it will only be slightly intriguing. I think that's more than you can say for classic "hello, world". -Dave -- David Abrahams [EMAIL PROTECTED] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Hello MPL world!
At 10:17 PM 1/6/2003, Howard Hinnant wrote: >On Monday, January 6, 2003, at 06:50 PM, David Abrahams wrote: > >> OK, I see your point. How about: >> >> template >> struct my_container >> : if_< >> and_< >>is_pointer >> , is_POD > >>> >> , impl1 >> , impl2 >>> ::type >> { >> ... >> }; > >Or maybe even just: > > template > struct my_container > : if_::value, impl1, impl2>::type > { > ... > }; These are the examples that resonate with me, particularly Howard's version. It looks so easy, and has obvious practical uses. It would motivate me. But it needs to be a complete, compilable, runable, program so I can try it, modify it, etc. --Beman ___ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost