Transforming a range back to the original type?

Steven Schveighoffer schveiguy at yahoo.com
Fri May 4 08:47:31 PDT 2012


On Fri, 04 May 2012 11:21:06 -0400, Jakob Ovrum <jakobovrum at gmail.com>  
wrote:

> On Friday, 4 May 2012 at 13:22:47 UTC, Steven Schveighoffer wrote:
>> Structs don't make very good containers.  A slice is not really a  
>> container.
>
> Most containers in std.container are structs. A struct can do everything  
> a class can do, for example, you can choose whether to use reference  
> semantics or not. So I don't think the assertion that structs aren't  
> good for containers is true, when they can do so much more than classes.  
> There is still debate whether std.container's containers should be  
> classes or structs, but even so, third-party containers might have  
> different requirements.

Non-reference semantics for containers are very bad.  Look at std::vector  
and how much inefficient code exists that passes it by value.

A container has one important property with regard to its elements, it  
*owns* the elements.  This screams reference semantics, because if you use  
value semantics, you need to *copy all the elements*.

Yes, a struct can do reference semantics, but it makes little sense to  
fight the type system and shoehorn it into reference semantics, when  
classes are reference types by default.

> It would obviously be a dead simple function, the question is whether  
> it's generally useful enough for the standard library, which I  
> personally don't see it being, at least not until I see at least one  
> good example.

I think the use case is, instead of defining some transformation function  
X as a member of a container, you:

1. define X as a function that accepts a range and returns a range
2. define a way to obtain a range of all elements from a container
3. define a way to construct a new container from a range.

Then you only have to define X once, instead of on every container type.   
And you can specialize some containers for X because of UFCS.  See Jacob's  
example.

> You would also have to decide on an explicit convention of construction  
> when T is a user-defined type (e.g. define a constructor taking an input  
> range), as such a function would effectively formalise it.

Most definitely.  I think any D-based container that can't be constructed  
 from a range of values isn't worth implementing.

> (By the way, the template instantiation shortcut syntax only works when  
> the only argument has exactly one token; your example code has an error.)

Yes, I realized this after posting, but figured the point would get across  
;)  I sometimes miss being able to do this in my real code, the omission  
of parentheses for template instantiation is an awesome feature!

-Steve


More information about the Digitalmars-d-learn mailing list