Thread overview
Miscellaneous question regarding std.container?
Nov 03, 2012
Tobias Pankrath
Nov 04, 2012
Jonathan M Davis
November 03, 2012
The std.container starts off with container primitives. Does this mean that all containers should support all these primitives?  Because I could never get c.length to work for a simple SList.

Are there formal definitions for  U and Stuff like  in (U)(U[] values...) and (string op, Stuff)(Stuff stuff);


struct SList(T);   //  Implements a simple and fast singly-linked list.

Since SList is a structure and in the excellent book by Andrei[A..u], he says for structure constructors (7.1.3.1) “…the compiler always defines the no-arguments constructor”.

This being the case shouldn’t one of the following compile?

SList(int) s1;
SList() s2;
SList s3;
auto s4 = SList;
auto s5 = SList();
auto s6 = SList(int);


And how does the std.array differ from the Array in std.container?  Is the std.array array a class while the std.container array a structure?

November 03, 2012
On Saturday, 3 November 2012 at 18:38:14 UTC, Too Embarrassed To Say wrote:
> The std.container starts off with container primitives. Does this mean that all containers should support all these primitives?  Because I could never get c.length to work for a simple SList.

That is a complete list of all possible primitives that can occur in the interface of  a std.container. However not every container defines every primitive. SList for example does not define length, because length is required (by convention) to be O(1), which is impossible with the current SList implementation.

> Are there formal definitions for  U and Stuff like  in (U)(U[] values...) and (string op, Stuff)(Stuff stuff);

No really, these are template parameters. U needs to be implicit convertible to T for an SList!T and Stuff needs to be an InputRange of U. Which you can only know if you read the source :-)


> struct SList(T);   //  Implements a simple and fast singly-linked list.
>
> Since SList is a structure and in the excellent book by Andrei[A..u], he says for structure constructors (7.1.3.1) “…the compiler always defines the no-arguments constructor”.
>
> This being the case shouldn’t one of the following compile?
>
> SList(int) s1;
> SList() s2;
> SList s3;
> auto s4 = SList;
> auto s5 = SList();
> auto s6 = SList(int);
You need an ! before the template parameter.

SList!int s1;
SList!(TypeTuple!(int, long)) s2;

Note that the container are reference types.
November 04, 2012
On Saturday, November 03, 2012 19:38:13 Too Embarrassed To Say wrote:
> The std.container starts off with container primitives. Does this mean that all containers should support all these primitives? Because I could never get c.length to work for a simple SList.

They're a list of common operations, each of which has a maximal algorithmic complexity, and some of which require that they not invalidate ranges (i.e. they have stable in their name). Cointainers should implement as many of them as they can, but if they can't implement a function with at most the given algorithmic complexity, or they can't implement a stable function without invalidating a range, or if the function just plain doesn't make sense for that container (e.g. reserve and capacity make no sense for linked lists), then they don't implement them. SList doesn't have length, because length can at worst be O(log n) (I thought that it was O(1), but the docs say O(log n)), and SList can't implement it in better than O(n).

> Are there formal definitions for  U and Stuff like  in (U)(U[]
> values...) and (string op, Stuff)(Stuff stuff);

Those are template parameters. Why would you need a formal definition? They're just generic names for the types, just like T in struct SList(T).

> struct SList(T);   //  Implements a simple and fast singly-linked
> list.
> 
> Since SList is a structure and in the excellent book by Andrei[A..u], he says for structure constructors (7.1.3.1) “…the compiler always defines the no-arguments constructor”.
> 
> This being the case shouldn’t one of the following compile?
> 
> SList(int) s1;
> SList() s2;
> SList s3;
> auto s4 = SList;
> auto s5 = SList();
> auto s6 = SList(int);

None of those will compile, because they all use templates incorrectly. SList by itself is not a type. It's a template for a type, so you can never use SList by itself. It must always be an instantiation of SList - e.g. SList! (int) or SList!int (the parens are optional when there's only one template argument). You're giving the type for T in struct SList(T) when you do SList!int. Without that, you haven't instantiated SList, and you're dealing with an actual type. So, your lines without parens there won't work, and your lines with parens but no ! won't work. You can generally avoid explicitly instantiating templated functions, because the types of the template arguments are inferred, but that doesn't happen with templated types. The compiler has no way of knowing what you want to instantiate SList with unless you tell it.

I'd advise that you read the section on templates in TDPL if you haven't already, since you clearly don't understand them.

> And how does the std.array differ from the Array in std.container?  Is the std.array array a class while the std.container array a structure?

There's no relation whatsoever. std.array is a module. std.container.Array is a type. std.array contains functions that operate on built-in arrays. std.container.Array is a container similar to C++'s vector or Java's ArrayList, which encapsulates an array but adds extra functionality on top of it.

- Jonathan M Davis