"Joel de Guzman" <[EMAIL PROTECTED]> escribió en el mensaje 002301c2a3c8$a8751fb0$a7564eca@kim">news:002301c2a3c8$a8751fb0$a7564eca@kim... > ----- Original Message ----- > From: "Fernando Cacciola" <[EMAIL PROTECTED]> > > > > I think it can be done in a way as to not make it confusing. > > For instance, iterators also have operator*() and ->(), yet they are not > > pointers. > > Aren't they? In the conceptual level? > In the conceptual level, yes, they're pretty much like pointers, but I ment that in spite of the fact that they conceptually look and behave like pointers, strictly, they _are_ not.
> > Certainly, they are _a lot_ more like pointers than optional<> because they > > have pointer semantics in terms of shallow-copy and aliasing, but, > > for instance, you cannot delete an iterator, but I don't think that > > Is a pointer required to point to heap allocated data? What about > int a = 3; int* ap = a; ? Isn't that a pointer? I can't delete ap. > OK. But that just shows that I picked up the wrong example. Let me try again: iterators do not have a corresponding "null pointer value" You cannot test for 'valid pointee' with an iterator alone; that's why you need to compare against "end" all the time. IOWs, the expression: if ( iter ) is meaningless with an iterator. This shows that at some extent they're not pointers anymore, just like optional<> > > the pointer-analogy had drawn peoplo into that sort of mistakes. > > For optional<>, the key to sucess resides in the way you present it, > > and in the way the pointer-like interface is used. > > > > > > For what its worth, I prefer the union concept. Union semantics clearly > > > state that > > > you can have either or (i.e., not both). > > Yes. > > > But I think that a container is even better, because containers inherently > > models the fact that you can have a value or not. > > I can easily give you a container that fails your definition: > Isn't char a[3]; a container? Yet, it does not "model(s) the fact that > you can have a value or not". What about tuples, are you saying > that that is not a container? > I was thinking about a variable size container. But you make a good point: the word 'container' alone doesn't imply that. A variable size container is closer in meaning becuase it can be empty() A variant is never empty. > > This is closer in meaning to optional than a union. > > Think again. Isn't variant a *container* that holds only one value > at a time? That supersets the definition of the optional AFAICT. > Exactly. It cannot hold 0 values. This is what makes variable-size (of at most 1) containers closer to the optional concept. > > It is an error to try to access one element of an empty container > > just as it is an error to try to access a non-existent value. > > It is also an error for a variant to access T from variant<T, nil_t> > if nil_t is in effect and T is therfore a "non-existent value". > Well, yes, you're right. I concede that, normally, you would always access T from the variant and not something else like nil_t. I overlooked this fact, partially, because this is not required by the union itself; it is the user responsability to do that; but I admit that a variant used for this purpose would require that, so it is almost the same situation than with a variable-size container (with capacity 1). > > The union mapping is good, but the container mapping is better becuase > > the undefined behaviour of invalid access is directly supported by the > > container concept, while the union concept requires the additional > > element of a type with semantics unfamiliar to C++. > > What semantics are you referring to? The semantics of > variant<T, nil_t>? optional<T>? maybe<T> ? All of these > are new grounds (and thus unfamiliar) to the C++ programmer. > I was actually refering to the semantics of nil_t; but I was overlooking that fact that you wouldn't even access nil_t on a variant, at least not if you used the variant purposedly to hold an optional T. > What's wrong with borrowing a well formed concept from > other languages? That's definitely better that concocting a > half-cooked version of what's already a mature concept in > other languages. > There's nothing wrong with that, but it is important to notice that on a different language there are different tools, so what works best on one does not necesarily work best on another. For instance, I don't know if you can have a stack-based fixed capacity and variable size container on Haskell. But you can have it on C++, so following this model in C++ make sense just as it makes sense to follow the union model. I'm not arguing against the union model; I'm just arguing that the variable-size-container also works; and IMO better, but even if it were not better, it is clearly not worse; and IMO, containers are more familiar to C++ programmers than _discriminated_ unions. But the difference is negligible, and I didn't want to imply otherwise. On both models you have a box which can have a 'T', but in the variable-size container, if you don't have a T you have nothing; while on the union model you have an X. T-or-nothing maps better IMHO to the optional T concept than T-or-else. But I know both models completely work. > > With a union-like interface, this is not so because the union has always > > a well defined state, so if you try to accesss an uninitialized optional, > > this model gives you nil_t. > > Wrong! Accessing T in variant<T, nil_t> does not give you nil_t. > Correct. It gives you nil_t if you ask for it but you wouldn't unless you're insane :-) But you are right, in practice, I will always try to extract a T and nothing else. > > > nil_t by itself is not undefined, so to make sense of the concept of > > optional value, which itself implies that the value might not exist, > > either the programmer or the interface-under-the-hood must make sure > > that the result nil_t is treated as a postcondition violation. > > If you trust my experience with this tool, I assure you that if you are > > accesing the value of a conceptually non-existent object, > > you've made a mistake on the code because the execution path > > should never had reached that point. > > This is why I prefer the container model: You cannot extract one > > element of an empty container. If you try, you get undefined behaviour. > > However, the syntax of a container interface does not help you > > to make sure you have checked for non-emptyness. Of course, > > this happens all the time with any container and it has alawys > > been the programmers responsability to make sure of the object > > you try to access is actually there. > > All these are based on a wrong premise. Are you sure you meant to say _all_ these? How about this part: > > If you trust my experience with this tool, I assure you that if you are > > accesing the value of a conceptually non-existent object, > > you've made a mistake on the code because the execution path > > should never had reached that point. Fernando Cacciola _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost