How to Instantiate struct defined in template

Jonathan M Davis jmdavisProg at gmx.com
Sat Sep 22 21:04:13 PDT 2012


On Sunday, September 23, 2012 05:49:06 Craig Dillabaugh wrote:
> Hello,
> I am trying to figure out how templates work and tried to define
> the
> following template to define vertices of any dimension and
> operations
> on them.
> 
> import std.stdio;
> import std.random;
> import std.range;
> import std.conv;
> import std.math;
> 
> /*
>    * T must be one of the floating point types
>    *   float, double, real _ I should be enforcing this.
>    */
> template  vt(T)
> {
>     struct vertex {
>       this(T[] crds...) {
>         if( crds.length < 2 ) {
>           throw new.Exception("To small!");
>         } else {
> 	coords.length = crds.length;
> 	foreach(ref v_coord, in_coord; lockstep(coords, crds))
> 	{
> 	  v_coord = in_coord;
> 	}
>         }
>       }
>       @property T x() { return coords[0];}
>       @property T y() { return coords[1];}
>       @property T z() { return ( coords.length < 3 ? T.nan :
> coords[2] ); }
>     }
> 
>     T euclid_dist(T a, T b) {
>       T sum = 0;
>       foreach( ref a_crd, ref b_crd; lockstep( a.coords, b.coords )
> ) {
>         sum += (a_crd - b_crd)*(a_crd - b_crd );
>       }
>       return sqrt(sum);
>     }
> } //End of template
> 
> int main(string argv[] ) {
> 	vt!(float).vertex v1(0.0,0.0);
> 	vt!(float).vertex v2(3.0,4.0);
> 	writefln("The distance between vertex 1 and vertex 2 is ",
> 		vt!(float).euclid_dist(v1, v2) );
> }
> 
> When I try to compile this I get the message:
> 
> vertex.d(57): Error: found 'v1' when expecting ';' following
> statement
> vertex.d(58): Error: found 'v2' when expecting ';' following
> statement
> 
> Lines 57 and 58 are the first two lines in my main() function. I
> can't figure out why, from the examples I've looked at I am using
> the syntax properly, but am clearly missing something.
> 
> Also, since I don't really know what I am doing any criticisms on
> how I am defining the vertex template are welcome.

Before anything, I'd question why you declared vt at all. If all you're 
putting in it is a single struct, then just templatize the struct directly:

struct Vertex(T)
{
    ...
}

Now, it looks like you have a free function in there as well - euclid_dist - 
but there's no reason to put that in the same template. Just templatize it 
directly. Then you get

T euclid_dist(T)(T a, T b) {...}

And main ends up looking something like

void main()
{
    auto v1 = Vertex!float(0.0, 0.0);
    auto v2 = Vertex!float(2.0, 4.0);
    writefln("The distance between vertex 1 and vertex 2 is %s",
             euclid_dist(v1, v2));
}

It's actually fairly to explicitly declare a template in D outside of 
eponymous templates. If you're dealing with a user-defined type or function, it 
almost always makes more sense to templatize them directly.

Now, as for the exact error message, it's because the syntax that you're using 
to define v1 and v2 is illegal. You'd need to do either

vt!float.vertex v1 = vt!float(0.0, 0.0);

or preferrably.

auto v1 = vt!float(0.0, 0.0);

You can't construct the type on the left-hand side of the assignment operator 
like that.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list