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