[boost] Re: Variant Library: access interface
templatetypename T void foo( T const ) { } int main() { boost::variantint,. v = 5; // Here I want to pass const reference to integer value of variant to function foo // foo( getint( v ) ); - type T is incorrect foo( ??? ); } I don't see why this wouldn't work. What is incorrect regarding type T? Try to compile and run this: #include iostream templatetypename T void foo( T const ) { std::cout typeid(T).name() std::endl; } templatetypename T struct get { operator T() { return m_t; } T m_t; }; int main() { foo( getint() ); } I see it as the difference between dynamic_cast with a reference type versus a pointer type. That is, the reference-based dynamic_cast throws, which as you note, works fine. But the pointer-based dynamic_cast provides a non-throwing mechanism as well (returns a null pointer). Thus, extract::check is the non-throwing analogue for extract. I don't argue that it may be used. I argue that it will be rarely used. In most cases when you access your variant you either know what type it holds by inspecting it's which() result or will use some kind of visitation. You may provide this form of value access but only as an addition to free form one. Gennadiy. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Variant Library: reflection
If the issue concerns you this much, you might propose something along the lines of BOOST_NO_EXCEPTIONS. That is, you might try: BOOST_NO_RTTI anyone? - Eric I did. As a user defined parameter. Terrie made a point that it should be config parameter cause some embedded compiler indeed does not provide this functionally (maybe because it's taking too much space to implement?). No consequences yet. Gennadiy. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Variant Library: top level const types
I think you misunderstand: What I'm arguing is that the usage case you propose here is itself erroneous. This is *not* an issue of whether I can implement the behavior. (In fact, I need to do additional work to prohibit it.) Let me know if you still disagree. I disagree. Let say I want to define type that will hold constant parameter that is represented either as constant int value or constant string that could be used to lookup the value in some kind of global table. So what I want is typedef boost::variantint const,std::string const GlobalParameter; GlobalParameter input_socket( 12345 ); // localhost::12345 GlobalParameter output_socket( MultiplexorSocket ); Is there anything wrong in such design? Gennadiy. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] boost::any feature request
Vladimir Prus wrote: Hi Maxim, And here are the Intel VTune results (see the sources for details): Creation Assignment struct 13383 27358 boost::any 3846 331870 TailoredAny 9151 310717 TailoredAnyLoki::SmallObject 3855 110022 IOW, TailoredAny behaves much worse on creation in default configuration. It behaves much better on assignment, in tuned configuration. Hmm.. It might be interesting to try a modified boost::any that uses boost/detail/quick_allocator.hpp. void * operator new(std::size_t) { return detail::quick_allocatorthis_type::alloc(); } void operator delete(void * p) { detail::quick_allocatorthis_type::dealloc(p); } needs to be added to any::holder. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Re: Variant Library: top level const types
Gennadiy Rozental wrote: So what I want is typedef boost::variantint const,std::string const GlobalParameter; GlobalParameter input_socket( 12345 ); // localhost::12345 GlobalParameter output_socket( MultiplexorSocket ); typedef boost::variantint, std::string GlobalParameter; GlobalParameter const input_socket( 12345 ); // localhost::12345 GlobalParameter const output_socket( MultiplexorSocket ); Same as vectorint const vs vectorint const. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [smart-ptr] Custom deallocator for scoped_ptr
Lars Gullik Bjønnes wrote: We find ourselves in want of a custom deallocator for scoped_ptr, but no such thing seems to exist now. Has this been thought of? If yes, what was the reason for not supporting this? If you want a shared_ptr-style runtime custom deallocator support, this is not supported because the overhead was (and is) considered unacceptable for scoped_ptr. Use shared_ptr instead. The alternative is template class T, class D = boost::checked_deleterT class scoped_ptr { public: // ... ~scoped_ptr() { D()(ptr); } }; The concern here is that the change may potentially break user code that uses a template template parameter to pass scoped_ptr/auto_ptr/shared_ptr/whatever_ptr as an argument. I'm not yet sure whether the increased functionality justifies breaking such code. OTOH I'm not sure whether such code even exists. ;-) So if someone has an opinion about this potential change to scoped_ptr, now is probably the right time to express it. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [smart-ptr] Custom deallocator for scoped_ptr
I think scoped_ptr needs to remain as it is. If we need this functionality a new scoped_deallocator may be the way to go. On Thursday, Apr 3, 2003, at 11:04 Europe/London, Peter Dimov wrote: Lars Gullik Bjønnes wrote: We find ourselves in want of a custom deallocator for scoped_ptr, but no such thing seems to exist now. Has this been thought of? If yes, what was the reason for not supporting this? If you want a shared_ptr-style runtime custom deallocator support, this is not supported because the overhead was (and is) considered unacceptable for scoped_ptr. Use shared_ptr instead. The alternative is template class T, class D = boost::checked_deleterT class scoped_ptr { public: // ... ~scoped_ptr() { D()(ptr); } }; The concern here is that the change may potentially break user code that uses a template template parameter to pass scoped_ptr/auto_ptr/shared_ptr/whatever_ptr as an argument. I'm not yet sure whether the increased functionality justifies breaking such code. OTOH I'm not sure whether such code even exists. ;-) So if someone has an opinion about this potential change to scoped_ptr, now is probably the right time to express it. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] [dynamic_bitset::reference] - questions to the users (and to the gurus)
Among the several changes I've planned to dynamic_bitset there's one which affects semantics and that, therefore, I would like to discuss with you a bit. Note however that the old semantics were never specified in the docs, so this would break nothing but adventurous usages of undocumented features on the users part. Here's the issue: dynamic_bitset::reference currently stores a pointer to its bitset object and an index. For that reason: - after a swap of bitsets, references come to refer to different elements: they get track of the address of the bitset they are referencing, and the bitset has changed its contents. - value changing operations on the dynamic_bitset *don't* invalidate references unless they make the corresponding index out of range (by shrinking the bitset). In other words: semantics are intrinsecally those of a *pair* (bitset address, index); as long as the index remains valid for the pointed to bitset everything is fine. But then one wonders: why not using an index directly? And even if, how could one use a reference considering that all its constructors are private? Both points above are the exact contrary of what one would expect by analogy with references, pointers, or iterators (The standard guarantees that no standard library swap() function invalidates any references, pointers, or iterators referring to *the elements* of the containers being swapped. To state it metaphorically: the elements change containers but references follow them). Now, the first question is: ok to change semantics and document the new behavior? (BTW, the new semantics can be implemented much more efficiently, e.g. by storing a pointer to a block and a *precomputed* mask) Second question: any interest in having this new referenceBlock as a separate class? (In this case dynamic_bitset::reference would really become a typedef as stated in the docs, rather than a nested class :-)) Now, for the gurus: this is the current interface of reference: class reference { friend class dynamic_bitsetBlock, Allocator; // the one and only non-copy ctor reference(dynamic_bitset bs_, size_type bit_); public: operator bool() const; // for x = b[i] bool operator~() const;// flips the bit reference flip(); // for b[i].flip(); reference operator=(bool value); // for b[i] = x reference operator|=(bool value); // for b[i] |= x reference operator=(bool value); // for b[i] = x reference operator^=(bool value); // for b[i] ^= x reference operator-=(bool value); // for b[i] -= x reference operator=(const reference j); // for b[i] = b[j] reference operator|=(const reference j); // for b[i] |= b[j] reference operator=(const reference j); // for b[i] = b[j] reference operator^=(const reference j); // for b[i] ^= b[j] reference operator-=(const reference j); // for b[i] -= b[j] }; Note the last two groups of 5 functions: they are identical except that those of the first group take a bool and those of the second one a const reference . But since we have an operator bool() const wouldn't the first group be enough? In effect, declaring the copy-assignment operator has the pleasant effect to force an explicit definition, showing that the shallow-copy is intentional, but what about the other 4 functions? What's their purpose? If we drop them, an expression like b[i] |= b[j] changes from (b.operator[](i)).operator |= ( b.operator[](j) ) to (b.operator[](i)).operator |= ( b.operator[](j).operator bool() ) But I can't see any problem with that, even with self-assignment. Am I missing something? Genny. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] indentation algorithm for stream objects
Larry Evans wrote: Wouldn't the following: *thisiomanip::setw(m_indent.length * m_indent.level)setfill(fill)fill; *thissetfill(fill); do essentially what indentor OutputFileType ::indent() does? Thanks. I didn't think of that. I'll implement it into the code (with the correction pointed out by Jason House). This implementation also requires the user to know when the beginning of line occurs. That does sound pretty reasonable, and I'm kinda wondering why I didn't do it in marg_ostream; however, marg_ostream doesn't require this, and I'm wondering whether other people think this feature is worth the extra complexity in marg_ostream. There are two possible ways I see at simplifying your marg_ostream: [1] Overload string operations only since you only really need to intercept '\n' characters - this appears to be the simpler of the two solutions (as there is no real need to overload for integer types, only strings and characters). [2] Write a stream buffer that intercepts the '\n' characters - this seems overly complicated and a little overkill. NOTE: I have not yet looked at the code for marg_ostream so I cannot give any more detailed comments on it at the moment. One of the reasons I chose not to have the '\n' character trigger the code to perform the indentation is that you could have code like: out.indent() This is a test '\n'; out.beginIndent(); out.indent() Indented '\n'; out.endIndent(); out.indent() End of test '\n'; It makes sense to have the new lines at the end of the output. If, however, the '\n' character triggered the indentation, you would need something like: out This is a test; out.beginIndent(); out \nIndented; out.endIndent(); out \nEnd of test; which is less intuitive and can lead to mistakes if you are not careful. The reason for this is that the indentation will be done at the wrong time and lead to incorrect alignment of the string Indented. Letting the user control *when* indentation occurs gives greater flexibility, for example if you were formatting an XML document, you could choose not to indent on CDATA sections, or pre elements in HTML. Another indentor advantage is there's no need to define operator for all the primitive types as was done in marg_ostream. That is due to the aim at keeping indentor's design as simple as possible, while giving it as much flexability as possible. Redefining the operator would have severly complicated the design. -rhd- mailto:[EMAIL PROTECTED] _ Express yourself with cool emoticons http://www.msn.co.uk/messenger ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Statistics code example
On Wednesday 02 April 2003 02:57 pm, Paul A. Bristow wrote: Sadly (but perhaps not too surpringly) this does not seem to work for MSVC 7.0 with complex. (OK without) Could you elaborate? What didn't work? Any ideas how to fix? I don't use MSVC. A full working example with at least a few comments might sell this better? Paul Paul A Bristow, Prizet Farmhouse, Kendal, Cumbria, LA8 8AB UK +44 1539 561830 Mobile +44 7714 33 02 04 Mobile mailto:[EMAIL PROTECTED] mailto:[EMAIL PROTECTED] -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Behalf Of Neal D. Becker Sent: Tuesday, April 01, 2003 2:26 PM To: [EMAIL PROTECTED] Subject: [boost] Statistics code example Here is an example of a class that can compute 2nd order stats that will work for either scalar or complex types. It could be made slightly more efficient. It uses abs(), relying on the trick that abs() is defined for both scalar float and complex. It could be improved by defining our own norm function for both scalar float and complex. (Unfortunately for efficiency, complex norm is defined in terms of abs, which uses sqrt, on at least some systems (libstdc++)). ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] [smart-ptr] Custom deallocator for scoped_ptr
On Thursday, April 3, 2003, at 05:04 AM, Peter Dimov wrote: So if someone has an opinion about this potential change to scoped_ptr, now is probably the right time to express it. I've been experimenting with: templateclass T, class D = detail::apply_delete class move_ptr; So far I like it. It is implemented so that the deallocator can also be a reference to a deallocator. Can be used like: templateclass T templateclass Y, class D shared_ptrT::shared_ptr(Y* p, D d) : ptr_(p) { move_ptrY, D hold(p, d); s_ = new detail::shared_ptr_deleterY, D(p, d); hold.release(); ... } -Howard ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] document translation into Japanese
At 04:01 AM 4/2/2003, k.t. wrote: And in translating, we found some incorrect expressions in boost document. We want to report them for feedback, then is it no problem to report them here? Is boost users mailing list better for it? This list is probably the best place. Thanks, -- Beman ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] Statistics code example
Neal D. Becker wrote: Could you elaborate? What didn't work? Any ideas how to fix? I don't use MSVC. Looking at the code, I think the problem is this (although I have not yet tried it): templatetypename T struct Stat_t std::complexT { typedef typename std::complexT::value_type value_t; }; MSVC 7 does not handle partial template specialization, so it will not compile (you'll need to remove the above specialization). It should work for MSVC 7.1 final beta, but I do not have a copy of it to verify. The solution would be to wrap the above in a guard statement similar to: #if !defined(BOOST_NO_PARTIAL_SPECIALIZATION) templatetypename T struct Stat_t std::complexT { typedef typename std::complexT::value_type value_t; }; #endif NOTE: I'm not sure if the BOOST_NO_PARTIAL_SPECIALIZATION name is correct, but you get the idea. Then, if there is partial specialization support the program will work as indented. Compilers (like MSVC 7) that do not have partial specialization support will then be able to use the program and it will still work because the imaginary component is not used in sumXsqr so the complex number is in essence a real number. There are several concerns with this: * there is no automatic conversion of a complex number to a real number, so this is not a complete solution * output to a stream would probably result in a display of the form: (x, y) I do not how how to get around these problems. -rhd- mailto:[EMAIL PROTECTED] _ Hotmail messages direct to your mobile phone http://www.msn.co.uk/mobile ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: [dynamic_bitset::reference] - questions to the users (and to the gurus)
On Thu, 03 Apr 2003 14:15:27 +0200, Gennaro Prota [EMAIL PROTECTED] wrote: Now, for the gurus: this is the current interface of reference: class reference { friend class dynamic_bitsetBlock, Allocator; // the one and only non-copy ctor reference(dynamic_bitset bs_, size_type bit_); Please don't scold me about the use of the term interface here. Just sloppy language. public: ... reference operator=(const reference j); // for b[i] = b[j] reference operator|=(const reference j); // for b[i] |= b[j] ... In case this is confusing: the declarations and the corresponding comments use the letter j with different meanings. I would have better written: reference operator=(const reference rhs); // for b[i] = b[j] ... Genny. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
RE: [boost] Statistics code example
I believe this conjecture is correct, but I am still eagerly awaiting 7.1 :-) This is quite interesting (though it needs Industrial Strengthening of course), and could usefully generate the higher moments and other statistical thingys too. And it makes me wonder if one could use a container like a circular buffer. I can think of applications where one would like new data to pour in continuously and to look back for mean (weighted Kalmanesque?), perhaps only a limited distance. Using a vector or valarray would imply it would grow for ever and run out of space eventually. (I think someone else suggested something of this sort?) Is the STL queue suitable? Paul Paul A Bristow, Prizet Farmhouse, Kendal, Cumbria, LA8 8AB UK +44 1539 561830 Mobile +44 7714 33 02 04 Mobile mailto:[EMAIL PROTECTED] mailto:[EMAIL PROTECTED] -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Behalf Of Reece Dunn Sent: Thursday, April 03, 2003 3:33 PM To: [EMAIL PROTECTED] Subject: Re: [boost] Statistics code example MSVC 7 does not handle partial template specialization, so it will not compile (you'll need to remove the above specialization). It should work for MSVC 7.1 final beta, but I do not have a copy of it to verify. The solution would be to wrap the above in a guard statement similar to: #if !defined(BOOST_NO_PARTIAL_SPECIALIZATION) templatetypename T struct Stat_t std::complexT { typedef typename std::complexT::value_type value_t; }; #endif ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Re: [boost] indentation algorithm for stream objects
Reece Dunn wrote: Larry Evans wrote: [snip] There are two possible ways I see at simplifying your marg_ostream: [1] Overload string operations only since you only really need to intercept '\n' characters - this appears to be the simpler of the two solutions (as there is no real need to overload for integer types, only strings and characters). [2] Write a stream buffer that intercepts the '\n' characters - this seems overly complicated and a little overkill. Agreed. I had to work at it IIRC. NOTE: I have not yet looked at the code for marg_ostream so I cannot give any more detailed comments on it at the moment. Thanks. I'll think some more about it, when I get some time. One of the reasons I chose not to have the '\n' character trigger the code to perform the indentation is that you could have code like: out.indent() This is a test '\n'; out.beginIndent(); out.indent() Indented '\n'; out.endIndent(); out.indent() End of test '\n'; It makes sense to have the new lines at the end of the output. If, however, the '\n' character triggered the indentation, you would need something like: [snip] which is less intuitive and can lead to mistakes if you are not careful. The reason for this is that the indentation will be done at the wrong time and lead to incorrect alignment of the string Indented. I disagree. The following (almost) line by line translation of your example to marg_ostream: ; marg_ostream mout(cout) ; unsigned i=0 ; mout This is a test i++ endl ; ++mout ; mout Indented endl ; --mout ; mout End of test endl produces: This is a test0 Indented End of test [snip] Another indentor advantage is there's no need to define operator for all the primitive types as was done in marg_ostream. That is due to the aim at keeping indentor's design as simple as possible, while giving it as much flexability as possible. Redefining the operator would have severly complicated the design. That's why I like your way; however, in the back of my mind, there's a feeling I started out that way (this was done years ago) and for some reason, after running some tests, found it better to do it this other way. I think the problem was I didn't always know when the beginning-of-line occured; hence, I needed the marg_ostream to keep track of this. I can't remember specifics yet. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: [dynamic_bitset::reference] - questions to the users (and to the gurus)
A couple of corrections to my previous post: And even if, how could one use a reference considering that all its constructors are private? All non-copy constructors, actually. Client code can easily create a reference object by copy: dynamic_bitset::reference ref = b[0]; This brings the question: should we disable copy construction? Note that vectorbool has a member function to swap two references // see 23.2.5 static void swap(reference x, reference y); which, of course, requires a copy constructor. Should dynamic_bitset have it too? In that case we could implement a private copy constructor, which would be available to dynamic_bitset::swap (for friendship) but not to the user; otherwise we could simply leave it undefined: private: reference(reference); // undefined In effect, declaring the copy-assignment operator has the pleasant effect to force an explicit definition, showing that the shallow-copy is intentional Sorry, I was thinking to the copy constructor (implicitly declared), that makes a shallow copy. The copy assignment operator does something completely different. Genny. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Variant Library: access interface
Gennadiy Rozental: templatetypename T void foo( T const ) { } int main() { boost::variantint,. v = 5; // Here I want to pass const reference to integer value of variant to function foo // foo( getint( v ) ); - type T is incorrect foo( ??? ); } I don't see why this wouldn't work. What is incorrect regarding type T? Try to compile and run this: #include iostream templatetypename T void foo( T const ) { std::cout typeid(T).name() std::endl; } templatetypename T struct get { operator T() { return m_t; } T m_t; }; int main() { foo( getint() ); } Sorry, I now understand. While I had planned to abandon this approach due to MSVC conformance problems, I see now it must be abandoned for a more significant reason. Thanks, Eric ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Variant Library: visitation algorithm
Gennadiy Rozental wrote: While I do agree O(1) is better than O(N), I would like to point out that it is usable only when the pseudo-variadic template interface is used (i.e., variantT1, T2, ..., TN as opposed to variantTypes). Why? And to be absolutely clear: what do you mean by it? By it I mean the use of a switch, as you propose. If variant is given types as a MPL-sequence (e.g., variant mpl::listT1, T2, ..., TN instead of variantT1, T2, ..., TN), then technique you propose will not work. Please prove me incorrect, but I don't think you can. (Note, however, that loop-unrolling is still possible, though ultimately it doesn't change the O(N) complexity of visitation.) Also, I am still not convinced that an unrolled if-else implementation would not be optimized in the same manner as a switch statement. That is, whether I do not know how smart are modern optimizers. But in general my understnding was that if-else form should use O(N) comparisons, while switch form should be compiled into jump with some computed offset. I'd be interested to know more about these assumptions before I spend a great deal of time writing code based upon them. Also possible, I'd like to note, is the use of a static array of function pointers. I'll look into this, too, but the space-overhead involved may be significant. Further, I would like to point out that we are debating integer O(1) vs. O(N) for integer-equality comparisons. While I am a proponent of limiting complexity, I would like to observe that you yourself suggested a cap N = 128. In sum, I'm not sure how pertinent this issue is at this point. I agree that by itself the difference is not that significant. But note that visitation is very basic operation in regards to variant type. Almost any activity that involve variant will include some kind of visitation (look into your implementation for example). Some people fight to eliminate extra level of indirection by using references vs. pointers. Or eliminate virtual function to prevent double resolution. In this case the difference could be much more significant (up to 128 times). So unless it's really unreasonably difficult to implement different visitation scheme, I see enough point to try to do this. I agree that visitation is the fundamental operation for variant. I'll look into it. Thanks, Eric ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] BOOST_HAS_THREADS in Win32
I'm new to boost. But should '#define BOOST_HAS_THREADS' be added to boost_1_30_0/config/platform/win32.hpp? Or is there a better way? Thanks. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Variant Library: variant size and strong guaranty
overview.) This technique is necessary to provide a general guarantee of strong exception-safety, which in turn is necessary to maintain a never empty invariant for variant. What is this invariant? And why is it that important. The invariant is quite straightforward: any object of type variantT1, T2, ..., TN contains exactly one object of type T1, T2, ..., or TN. From this it seems that in above passage (This technique is necessary ...) you switched an order of importance: In fact you need double storage to implement never empty invariant (in other case you would need during copy/assignment to first destroy current object), that is necessary to implement strong guaranty. Isn't it? I am well aware, of course, of the trade-offs made by the use of this technique. Thus the decision is not set in stone, and I'd be willing to consider arguments against it. I will make two final notes, however. 1) In addition to its role in enabling recursive variants, boost::incompleteT provides a convenient way to increase space efficiency (though at the expense of speed efficiency due to heap allocation). Note though that this is only because incomplete wraps a T*, which is small. It does *not* disable the double-storage technique. 2) For every type supporting non-throwing move operations, I have implemented variant to use single-storage. As a (trivial) proof of this, boost::has_nothrow_copy types *do* currently avoid the double-storage overhead.) Of course, until Boost.Move becomes a reality this is nearly all but meaningless for the vast majority of types. Several notes: 1. Intrinsic types have nothrow move constructor, so should follow second case road. Isn't it? 2. Could type that implements swap() method somehow follow the second case road also? For example, could you somehow deduce T* from buffer and swap it with local copy of the argument? 3. Could you use placement copy into local to assign storage and then memcopy it to variant storage? It wouldn't work with all types but may work in many cases isn't it? Here we would have different tradeoff. 4. Whatever way these matters will be decided I think it should be carefully documented so the user have a perfect understanding of possible choices. Another approach might be to take advantage of the introduction of 'void' content. Since 'void' content would introduce the notion of an empty variant, it *might* (see below for my strong reservations) make sense to disable the double-storage technique for variants with allowable empty (i.e. void content) states. While this is certainly quite implementable, I feel a bit uneasy about hinging variant's exception-safety guarantees on such a small point as whether 'void' content is allowed. I imagine it would not only make variant more confusing to use but also may not satisfactorily solve the problem of delegating the space-vs-safety decision to the user. I agree on that. I would rather have a variant of variant (;-)) that doesn't have strong guaranty at all. Separate issue is the type of which field. Having it as int is an This is implementation issue that affect the library design (it affects an abstraction overhead). So it's as important as issues above. So long as variant::which() returns an int, I don't see how it is anything other than a design issue: in terms of space efficiency, the difference between sizeof(char) and sizeof(int) is constant. I do not want to argue on terms. My point is that this implementation detail make variantint,short size at least 6 instead of 3. 100% difference. So let's just fix it before release. Gennadiy. ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost