Re: 'auto' with AA

2014-04-28 Thread David Held via Digitalmars-d-learn

On 4/27/2014 9:32 PM, Ali Çehreli wrote:

fOn 04/27/2014 06:00 PM, David Held wrote:

  I would like to do something like this:
 
  Foo[Bar][Baz] nestedAA;
  auto innerAA = nestedAA[someBaz];
  innerAA[someBar] = someFoo;
  assert(someFoo in nestedAA[someBaz]);

in operator uses a key, not a value. This should work:

 assert(someBar in nestedAA[someBaz]);


Sorry, that is what I meant to say.

That is, modifying nestedAA through innerAA does not seem to work, which 
is why I assumed it was a copy.  However, I'm pretty sure that if I use 
auto on an array, I will get a reference:


int[][] matrix = [[1, 2, 3, 4]];
auto array = matrix[0];
array[3] = 42;
assert(matrix[0][3] == 42);

This works just fine.  I assumed that AAs were like arrays, and thus, 
would work like references.  Here is a compilable example which fails:


void main()
{
double[int][string] nestedAA;
nestedAA[test] = null;
auto innerAA = nestedAA[test];
innerAA[42] = 3.14;
assert(42 in nestedAA[test]);
}

Note that I can even assign 'null' to the nested AA, which implies to me 
that it's a reference type!  Now, the problem may be that null is 
exactly what gets assigned to innerAA.  But then, why am I able to 
happily index it on the very next line?  And what exactly does it mean 
for an AA to be assigned 'null'?  This is perfectly legal, but I don't 
know what it means:


double[int] aa = null;

It appears to be a NOP, and indistinguishable from:

double[int] aa;

In fact, this appears to be the source of the problem.  If I change the 
null assignment above to:


nestedAA[test] = [1:1.0];

then everything works as expected, which means that innerAA really is a 
reference.  What is really bizarre is this idea that it starts out as a 
presumed null reference, and becomes instantiated through use.  Note 
that this is inconsistent with arrays:


double[] a = null;
a[0] = 3.14;// Range violation

I suppose the difference is that naming an invalid key in an AA inserts 
the key, but naming an invalid index in an array does not.  What is 
peculiar is that the above is a *range violation* and not an *access 
violation*.  It seems to me that the real problem is that a doesn't 
*refer to an actual array*.  So how can an index into 'a' violate its range?


The problem I have with the AA solution above is that I have to create 
some mapping to instantiate the nested AA.  I thought I would be 
clever and create a default initializer, like so:


nestedAA[test] = (double[int]).init;

Unfortunately, this appears to be equivalent to assigning null, which I 
assume is the actual value of .init above[1].  Of course, arrays and AAs 
are magical types in D, but it is a little frustrating that an empty 
initializer is reduced to the null initializer, even though the empty 
state is not the same as the null state:


double[int][string] nestedAA;
nestedAA[test] = null;
auto innerAA = nestedAA[test];
assert(innerAA.length == 0);// empty
assert(innerAA is null);// null
innerAA[42] = 3.14;
assert(innerAA !is null);   // not null
innerAA.remove(42);
assert(innerAA.length == 0);// empty
assert(innerAA !is null);   // still not null!

If there were an initializer which put the AA in the final state above, 
then I would be happy.  I'm sure that .init == null for performance 
reasons, but I don't see why there isn't some initializer syntax which 
creates a truly empty-but-not-null state, other than that not enough 
people needed it.  I propose something like:


double[int] aa = [void:void];
assert(aa.length == 0);
assert(aa !is null);

Unfortunately, this is exactly backwards.  This *should* be the syntax 
to make a null AA, and .init should make the empty one.  But history 
has prevented that solution.  Anything I'm missing?


Dave

[1] Unfortunately, .init is not documented here: 
http://dlang.org/hash-map.html even though it is documented for arrays




Is this a bug?

2014-04-28 Thread Andrey via Digitalmars-d-learn
Could anyone please explain to me, why do I have error message on 
this piece of code?


alias short Type1;
alias Type1[100]* Type2; // pointer to an array
struct Type3
{
Type2 f
}
void foo()
{
   Type3* b;
   Type1  d;
   d = b.f[10]; // compilation error: cannot implicitly convert 
expression ((*b).f[10]) of type short[100] to short

   d = b.f[0][10]; // ok
}

Thank you in advance


Re: Is this a bug?

2014-04-28 Thread John Colvin via Digitalmars-d-learn

On Monday, 28 April 2014 at 08:58:41 UTC, Andrey wrote:
Could anyone please explain to me, why do I have error message 
on this piece of code?


alias short Type1;
alias Type1[100]* Type2; // pointer to an array
struct Type3
{
Type2 f
}
void foo()
{
   Type3* b;
   Type1  d;
   d = b.f[10]; // compilation error: cannot implicitly convert 
expression ((*b).f[10]) of type short[100] to short

   d = b.f[0][10]; // ok
}

Thank you in advance


not a bug.

b.f[10] is indexing the pointer to the array, not the array 
itself.


b.f[0][10] is indexing the array (with the 10), but I would argue 
it is better to write *(b.f)[10] so as to be clear that f is not 
an array.


What is the reason you are using a pointer to a struct containing 
a pointer to a static array? It's often not necessary to work 
like that.


Re: Is this a bug?

2014-04-28 Thread Andrey via Digitalmars-d-learn

not a bug.

b.f[10] is indexing the pointer to the array, not the array 
itself.


b.f[0][10] is indexing the array (with the 10), but I would 
argue it is better to write *(b.f)[10] so as to be clear that f 
is not an array.


thank you, John.

compiler said that '*(b.f)[10]' is deprecated, and I should write 
like this


void foo()
{
   Type3 b;
   Type1  d;
   d = *(b.f[10]).ptr;
}

which looks completely weird for me...

What is the reason you are using a pointer to a struct 
containing a pointer to a static array? It's often not 
necessary to work like that.


it is just a sample... in real code the struct contains a lot of 
fields


Re: Is this a bug?

2014-04-28 Thread John Colvin via Digitalmars-d-learn

On Monday, 28 April 2014 at 09:36:08 UTC, Andrey wrote:

not a bug.

b.f[10] is indexing the pointer to the array, not the array 
itself.


b.f[0][10] is indexing the array (with the 10), but I would 
argue it is better to write *(b.f)[10] so as to be clear that 
f is not an array.


thank you, John.

compiler said that '*(b.f)[10]' is deprecated, and I should 
write like this


void foo()
{
   Type3 b;
   Type1  d;
   d = *(b.f[10]).ptr;
}


struct T
{
int[10]* f;
}

void main()
{
int[10] test;
T t = T(test);
T* b = t;

auto d = (*(b.f))[4]; //ugly but clear.
d = b.f[0][4]; //prettier but less clear.
}

note the extra brackets on the ugly one, I forgot them before.


Re: Is this a bug?

2014-04-28 Thread bearophile via Digitalmars-d-learn

Andrey:

Could anyone please explain to me, why do I have error message 
on this piece of code?


In this thread you are doing some mistakes. This code seems OK:

alias TData = short;
alias TArray = TData[100];

struct MyStruct {
TArray* arrPtr;
}

void main() {
MyStruct* t3 = new MyStruct(new TArray[1].ptr);
TData data0 = (*t3.arrPtr)[99];
}


D is working as designed. (The only small problem is that you 
can't new a fixed size array, so I have had to allocate a 
dynamic array of TArray of length 1 and take the pointer to its 
first item. Another alternative solution is to wrap TArray into a 
struct.)


Such kind of code is possible in D, but it should be quite 
uncommon in library code (and it can't be marked safe). There are 
usually simpler ways to do similar things in D. So perhaps there 
are ways to simplify your data structure (here I have kept the 
same structure you have used in the example).


Bye,
bearophile


Pointer to template types?

2014-04-28 Thread Chris via Digitalmars-d-learn
I need an array that contains pointers to types created via 
template. To stick to my usual example:


Person!(string)

How can I make an array with pointers to concrete instances of 
Person!(string)?


Something like this only with pointers, i.e. buf holds pointers 
to concrete Person!(string)s:


Appender!(Person!(string)[]) buf = appender!(Person!(string)[]);

Thanks in advance.


Re: Pointer to template types?

2014-04-28 Thread bearophile via Digitalmars-d-learn

Chris:

I need an array that contains pointers to types created via 
template. To stick to my usual example:


Person!(string)

How can I make an array with pointers to concrete instances 
of Person!(string)?


Every template creates a new type, so you can't put them as they 
are in an array. There are various solutions, none nice. You can 
try with a wrapper that performs type erasure, or simpler you can 
make all the same type giving them the string at run-time. 
Another solution is use OOP, something like (untested and I am 
not sure):


abstract class APerson {}
class Person(string name) : APerson {}

Bye,
bearophile


Re: Pointer to template types?

2014-04-28 Thread Chris via Digitalmars-d-learn

On Monday, 28 April 2014 at 10:32:18 UTC, bearophile wrote:

Chris:

I need an array that contains pointers to types created via 
template. To stick to my usual example:


Person!(string)

How can I make an array with pointers to concrete instances 
of Person!(string)?


Every template creates a new type, so you can't put them as 
they are in an array. There are various solutions, none nice. 
You can try with a wrapper that performs type erasure, or 
simpler you can make all the same type giving them the string 
at run-time. Another solution is use OOP, something like 
(untested and I am not sure):


abstract class APerson {}
class Person(string name) : APerson {}

Bye,
bearophile


So there is no way of filling an array with something like

Person!(string) *pptr;

foreach(person; people) {
  buf ~= person;
}


Re: Pointer to template types?

2014-04-28 Thread Chris via Digitalmars-d-learn

On Monday, 28 April 2014 at 10:32:18 UTC, bearophile wrote:

Chris:

I need an array that contains pointers to types created via 
template. To stick to my usual example:


Person!(string)

How can I make an array with pointers to concrete instances 
of Person!(string)?


Every template creates a new type, so you can't put them as 
they are in an array. There are various solutions, none nice. 
You can try with a wrapper that performs type erasure, or 
simpler you can make all the same type giving them the string 
at run-time. Another solution is use OOP, something like 
(untested and I am not sure):


abstract class APerson {}
class Person(string name) : APerson {}

Bye,
bearophile


So there is no way of filling an array with something like

Person!(string) *pptr;

foreach(person; people) {
   buf ~= person;
}


Re: Pointer to template types?

2014-04-28 Thread Rene Zwanenburg via Digitalmars-d-learn

On Monday, 28 April 2014 at 10:40:49 UTC, Chris wrote:

So there is no way of filling an array with something like

Person!(string) *pptr;

foreach(person; people) {
   buf ~= person;
}


Person!(string)*[] arr;

Like this?


Re: Pointer to template types?

2014-04-28 Thread Chris via Digitalmars-d-learn

On Monday, 28 April 2014 at 10:44:18 UTC, Rene Zwanenburg wrote:

On Monday, 28 April 2014 at 10:40:49 UTC, Chris wrote:

So there is no way of filling an array with something like

Person!(string) *pptr;

foreach(person; people) {
  buf ~= person;
}


Person!(string)*[] arr;

Like this?


Exactly, just tried it, this works. I tried various types of 
syntax and just couldn't get it right. Thanks a million.


Re: Pointer to template types?

2014-04-28 Thread bearophile via Digitalmars-d-learn

Chris:


So there is no way of filling an array with something like

Person!(string) *pptr;

foreach(person; people) {
   buf ~= person;
}


So you want an array filled with instances of the same 
instantiation, sorry, I misunderstood your problem for a more 
complex one :-)


Bye,
bearophile


Re: Is this a bug?

2014-04-28 Thread Andrey via Digitalmars-d-learn

bearophile, John, probably, my example was not clear...

The code below works.

alias short Type1;
alias Type1[100]* Type2; // if I take out '*' I will have to type 
it everywhere, because arrays in D2 always 'by value'


struct Type3
{
Type1 key;
int  flags;
int  arrLen;
Type2 f; // this struct can be *optionally* extended by the array
}

void foo(Type3* b)
{
   Type1  d;
   d = (*(*b).f)[10];
}

Thank you, I appreciate your help!!


Re: Is this a bug?

2014-04-28 Thread bearophile via Digitalmars-d-learn

Andrey:


alias short Type1;


The alias X Y; syntax is going to be deprecated, so use alias 
Y = X; if your compiler already supports it.



alias Type1[100]* Type2; // if I take out '*' I will have to 
type it everywhere, because arrays in D2 always 'by value'


Adding the * everywhere could be a good thing, because it makes 
the code more explicit. Even in Linux kernel typedefs that just 
mask out a pointer are not appreciated a lot. D code that uses 
pointers to fixed size arrays is very uncommon in D, so adding a 
* there is not going to cause troubles.




struct Type3
{
Type1 key;
int  flags;
int  arrLen;
	Type2 f; // this struct can be *optionally* extended by the 
array

}


The common way to create a variable length struct in D is to use 
a zero length fixed size array (and no pointers):


struct Type3 {
Type1 key;
int flags;
int arrLen;
Type1[0] f;
}


But if you don't mind the double indirection using a dynamic 
array is simpler:


struct Type3 {
Type1 key;
int flags;
Type1[] f;
}

Bye,
bearophile


How to use the result of __traits( allMembers , T ) with string mixins ?

2014-04-28 Thread ParticlePeter via Digitalmars-d-learn
DMD tells me Error: variable m cannot be read at compile time, 
but why ?


[code]
struct MyStruct {
float float_value = 0.0f ;
ubyte ubyte_value = 2 ;
}

enum members = [ __traits( allMembers , MyStruct ) ] ;

foreach( m ; members )  {
	mixin( writeln(  ~ m ~  , \ : \ , ( MyStruct. ~ m ~ 
.offsetof ) ; ) ;

}
[\code]

I also tried ref m and foreach( i ; 0..members.length ) with 
m[i]. A simple writeln( m or m[i] ) always  worked.
I read the limitation of String Mixins and Compile Time Function 
Execution here: http://dlang.org/function.html#interpretation
But it doesn't make sense to me as members are enum values and 
known at compile time.


What am I doing wrong, and how could it be done ?

Regards, ParticlePeter


Re: How to use the result of __traits( allMembers , T ) with string mixins ?

2014-04-28 Thread Andrej Mitrovic via Digitalmars-d-learn

On Monday, 28 April 2014 at 13:52:52 UTC, ParticlePeter wrote:
DMD tells me Error: variable m cannot be read at compile 
time, but why ?


Because 'static foreach' is not an explicit feature yet, so it 
depends on the context. When you wrap the trait via:


[__traits(allMembers, MyStruct)]

You're creating an array, and foreach will *not* by default 
attempt to become a static foreach, even if the array is known at 
compile-time. If you remove the parentheses it will work. You've 
had a few bugs in the mixin code though, anyway here's the 
working sample:


-
import std.stdio;

struct MyStruct
{
float float_value = 0.0f;
ubyte ubyte_value = 2;
}

enum members = __traits(allMembers, MyStruct);

void main()
{
foreach (m; members)
{
mixin(writeln( ` ~ m ~ ` , \ : \ , ( MyStruct. ~ m 
~ .offsetof ) ););

}
}
-


Re: Is this a bug?

2014-04-28 Thread Steven Schveighoffer via Digitalmars-d-learn
On Mon, 28 Apr 2014 06:04:53 -0400, John Colvin  
john.loughran.col...@gmail.com wrote:



On Monday, 28 April 2014 at 09:36:08 UTC, Andrey wrote:

not a bug.

b.f[10] is indexing the pointer to the array, not the array itself.

b.f[0][10] is indexing the array (with the 10), but I would argue it  
is better to write *(b.f)[10] so as to be clear that f is not an array.


thank you, John.

compiler said that '*(b.f)[10]' is deprecated, and I should write like  
this


void foo()
{
   Type3 b;
   Type1  d;
   d = *(b.f[10]).ptr;
}


struct T
{
int[10]* f;
}

void main()
{
int[10] test;
T t = T(test);
T* b = t;

auto d = (*(b.f))[4]; //ugly but clear.
d = b.f[0][4]; //prettier but less clear.
}

note the extra brackets on the ugly one, I forgot them before.


You don't need them. (*b.f)[4] works. '.' has precedence over '*'.

-Steve


Re: How to use the result of __traits( allMembers , T ) with string mixins ?

2014-04-28 Thread ParticlePeter via Digitalmars-d-learn

On Monday, 28 April 2014 at 13:57:56 UTC, Andrej Mitrovic wrote:

On Monday, 28 April 2014 at 13:52:52 UTC, ParticlePeter wrote:
DMD tells me Error: variable m cannot be read at compile 
time, but why ?


Because 'static foreach' is not an explicit feature yet, so it 
depends on the context. When you wrap the trait via:


[__traits(allMembers, MyStruct)]

You're creating an array, and foreach will *not* by default 
attempt to become a static foreach, even if the array is known 
at compile-time. If you remove the parentheses it will work. 
You've had a few bugs in the mixin code though, anyway here's 
the working sample:


-
import std.stdio;

struct MyStruct
{
float float_value = 0.0f;
ubyte ubyte_value = 2;
}

enum members = __traits(allMembers, MyStruct);

void main()
{
foreach (m; members)
{
mixin(writeln( ` ~ m ~ ` , \ : \ , ( MyStruct. ~ 
m ~ .offsetof ) ););

}
}
-


Thank you very much, it works. I never came so far to see those 
mixin errors at all :-)
I found the code with parenthesis in the dlang __traits docs and 
also Philippe Sigauds D Templates, and I haven't seen any other 
example which works without them. So, when to use which syntax ( 
for which purpose ) ? Is this clarified somewhere ?

Regards, ParticlePeter


Re: How to use the result of __traits( allMembers , T ) with string mixins ?

2014-04-28 Thread Andrej Mitrovic via Digitalmars-d-learn
On 4/28/14, ParticlePeter via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:
 I found the code with parenthesis in the dlang __traits docs and
 also Philippe Sigauds D Templates, and I haven't seen any other
 example which works without them. So, when to use which syntax (
 for which purpose ) ?

If you need to store the tuple as an array to some variable, then you
would use that syntax. It all depends on what you're trying to do from
the call site. Ultimately it won't matter much once we finally get a
proper 'static foreach' feature in D.


Re: import with renaming and public import inside module

2014-04-28 Thread anonymous via Digitalmars-d-learn

On Monday, 28 April 2014 at 00:52:50 UTC, ketmar wrote:

module my.module;
public import other.module;
…

module mainprogram;
import my.module;

now i can access other.module symbols without qualifiers


and another case:
module mainprogram;
import zmod = my.module;

now i CAN'T access other.module symbols without qualifiers. the 
only way to access 'em is to use horrible 
'zmod.other.module.symbol', which completely defeats my 
purposes for public imports in my.module.


`zmod.symbol` works, too.

can i use import renaming, but still access my.module public 
imports as if there was no renaming?


I don't think so. The point of the renamed import is that you 
have to use the new name. If you want the new name to be 
optional, import the module twice:

import my.module;
import zmod = my.module;
This way both `symbol` and `zmod.symbol` work.




[...]


the question is: is such behaviour of 'import' intentional, or 
this is just bug and it will be fixed eventually?


As far as I can see, everything works as intended.


Re: Is this a bug?

2014-04-28 Thread John Colvin via Digitalmars-d-learn
On Monday, 28 April 2014 at 14:02:33 UTC, Steven Schveighoffer 
wrote:
On Mon, 28 Apr 2014 06:04:53 -0400, John Colvin 
john.loughran.col...@gmail.com wrote:



On Monday, 28 April 2014 at 09:36:08 UTC, Andrey wrote:

not a bug.

b.f[10] is indexing the pointer to the array, not the array 
itself.


b.f[0][10] is indexing the array (with the 10), but I would 
argue it is better to write *(b.f)[10] so as to be clear 
that f is not an array.


thank you, John.

compiler said that '*(b.f)[10]' is deprecated, and I should 
write like this


void foo()
{
  Type3 b;
  Type1  d;
  d = *(b.f[10]).ptr;
}


struct T
{
int[10]* f;
}

void main()
{
int[10] test;
T t = T(test);
T* b = t;

auto d = (*(b.f))[4]; //ugly but clear.
d = b.f[0][4]; //prettier but less clear.
}

note the extra brackets on the ugly one, I forgot them before.


You don't need them. (*b.f)[4] works. '.' has precedence over 
'*'.


-Steve


The extra ones I referred to were the outer ones. Nonetheless, 
you're example is correct.


Re: 'auto' with AA

2014-04-28 Thread Ali Çehreli via Digitalmars-d-learn

On 04/28/2014 12:12 AM, David Held wrote:

  Here is a compilable example which fails:

 void main()
 {
  double[int][string] nestedAA;
  nestedAA[test] = null;

I think I see what's going on. The line above has almost no effect. For 
example, it does not populate test with an empty double[int] AA. I 
think there is conceptually an entry but that entry will be created 
lazily when an element is added to it.


  auto innerAA = nestedAA[test];

That line is not a reference to test but another null:

assert(innerAA is null);

  innerAA[42] = 3.14;

That entry populates the local AA. The test entry is still null.

  assert(42 in nestedAA[test]);

And that line fails.

Ali



Re: How to use the result of __traits( allMembers , T ) with string mixins ?

2014-04-28 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Apr 28, 2014 at 5:45 PM, Andrej Mitrovic via
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:

 If you need to store the tuple as an array to some variable, then you
 would use that syntax. It all depends on what you're trying to do from
 the call site. Ultimately it won't matter much once we finally get a
 proper 'static foreach' feature in D.

I guess a common use case is to create an array  with [__traits(...)],
and use it inside a function, iterating on it and creating a string
with the elements. The string is then mixed in with a CTFE call.

string makeCode(...) {
enum members = [ __traits(allMembers, MyStruct) ];

string result;
foreach (m; members)
{
result ~= writeln( ` ~ m ~ ` , \ : \ , ( MyStruct. ~ m ~
.offsetof ) ););
}
return result;
}

mixin(makeCode());

I don't know what I used it for in the tutorial, though :-)


Re: How to use the result of __traits( allMembers , T ) with string mixins ?

2014-04-28 Thread Dicebot via Digitalmars-d-learn
On Monday, 28 April 2014 at 17:40:54 UTC, Philippe Sigaud via 
Digitalmars-d-learn wrote:

On Mon, Apr 28, 2014 at 5:45 PM, Andrej Mitrovic via
Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:

If you need to store the tuple as an array to some variable, 
then you
would use that syntax. It all depends on what you're trying to 
do from
the call site. Ultimately it won't matter much once we finally 
get a

proper 'static foreach' feature in D.


I guess a common use case is to create an array  with 
[__traits(...)],
and use it inside a function, iterating on it and creating a 
string

with the elements. The string is then mixed in with a CTFE call.

string makeCode(...) {
enum members = [ __traits(allMembers, MyStruct) ];

string result;
foreach (m; members)
{
result ~= writeln( ` ~ m ~ ` , \ : \ , ( 
MyStruct. ~ m ~

.offsetof ) ););
}
return result;
}

mixin(makeCode());

I don't know what I used it for in the tutorial, though :-)


You can do the same iterating directly over allMembers list, why 
would you prefer array here?


Re: How to use the result of __traits( allMembers , T ) with string mixins ?

2014-04-28 Thread Philippe Sigaud via Digitalmars-d-learn
On Mon, Apr 28, 2014 at 8:20 PM, Dicebot via Digitalmars-d-learn
digitalmars-d-learn@puremagic.com wrote:

 You can do the same iterating directly over allMembers list, why would you
 prefer array here?

Hmm, indeed. One advantage would be to get a range, and thus the power
and filtering, mapping and co.


logging

2014-04-28 Thread xtimoner via Digitalmars-d-learn

synchronized class EventLog{
void opCall(string s){
std.file.append(logfile.txt, s);
}
}

shared EventLog eventLog;

Pleas, is it multithread safe and prefered way?


Re: logging

2014-04-28 Thread Ali Çehreli via Digitalmars-d-learn

On 04/28/2014 01:16 PM, xtimoner wrote:

 synchronized class EventLog{
  void opCall(string s){
  std.file.append(logfile.txt, s);
  }
 }

 shared EventLog eventLog;

 Pleas, is it multithread safe and prefered way?

Only if there is only one EventLog object. A synchronized class means 
that there can be only one member function executed on the same object 
at a given time. Your code is the equivalent of the following:


class EventLog{
void opCall(string s){
synchronized (this) {// -- NOTE (this)
std.file.append(logfile.txt, s);
}
}
}

So, opCall (and other member functions) is synchronized on a particular 
object.


If you have more than one EventLog, then they can write to the same file 
at the same time and that would be a problem.


Ali



Re: Pointer to template types?

2014-04-28 Thread Jesse Phillips via Digitalmars-d-learn

On Monday, 28 April 2014 at 10:40:49 UTC, Chris wrote:

Person!(string) *pptr;


Just wanted to point out, the above is C style and not 
recommended.


Person!(string)* pptr, pptr2, pptr3;

In D the pointer is part of the type not the variable (all three 
are pointers, unlike C where only the first would be a pointer). 
By placing the pointer on the variable I do not describe the 
types correctly.


Person!(string) *pptr, pptr2, pptr3;

This should help when wanting to use more complex types:

Person!(string)*[string][][char]* papp; //:)

used like :(I don't know my precedence):

*((*papp)['c'][1][hello])