Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 14, 2009 Template classes | ||||
---|---|---|---|---|
| ||||
Attachments: | So, the attached is supposed to be a class that creates a vector of any type (I would like it to only take numerical values (int, float, real, double, etc), however, I am ok with it taking others (not that I see why someone would use it that way). I tried to compile it with the following, but it won't compile. I don't really understand the errors I'm getting either. Can someone tell me what I'm doing wrong? If you need more information, let me know. -Andrew void testvector() { auto v = new Vector!(float)(3, 12.0); writefln(v.toString()); int n = 0; while (n < n.size()) { v[n] = n; } writefln(v.toString()); } |
April 14, 2009 Re: Template classes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Spott | On Wed, 15 Apr 2009 01:01:28 +0400, Andrew Spott <andrew.spott@gmail.com> wrote:
> So, the attached is supposed to be a class that creates a vector of any type (I would like it to only take numerical values (int, float, real, double, etc), however, I am ok with it taking others (not that I see why someone would use it that way).
>
> I tried to compile it with the following, but it won't compile. I don't really understand the errors I'm getting either.
>
> Can someone tell me what I'm doing wrong? If you need more information, let me know.
>
> -Andrew
>
> void testvector() {
> auto v = new Vector!(float)(3, 12.0);
> writefln(v.toString());
> int n = 0;
>
> while (n < n.size()) {
> v[n] = n;
> }
>
> writefln(v.toString());
>
> }
You've got quite a few errors in your code:
module vector;
private import std.string;
class Vector(T) {
private:
T[] v;
// int nn; // there is no need to store a size of array separately. It is available as v.length
public:
this() {
}
this(int n) {
// nn = n; // not needed
v = T[n]; // wrong, should be: v = new T[n];
}
this(int n, T a) {
// nn = n;
v = T[n]; // same here (see above)
while (n > 0) { // v[] = a; is faster and does the same as the loop below
n--;
v[n] = a;
}
}
T opIndex(int n, int m) { // this won't work, because float is not an array
return v[n][m]; // try this: T opIndex(int n) { return v[n]; }
}
opIndexAssign(T)(T a, int n, int m) { // no need for a template, also you forgot to write function return type
v[n][m] = a; // should be: void opIndexAssign(int n, T a) { v[n] = a; }
}
int size() {
return nn; // should be: return v.length;
}
string toString() {
string s = "[";
int n = 0;
while ( n < nn) {
s ~= v[n] ~ ", ";
}
return s ~ "]";
}
~this() { // no need for this one
}
}
void testvector() {
auto v = new Vector!(float)(3, 12.0);
writefln(v.toString());
int n = 0;
while (n < n.size()) { // infinite loop
v[n] = n;
}
writefln(v.toString());
}
Also, try using foreach instead of while and for loops.
For example,
string toString() {
if (v.length == 0) return "[]";
string s = "[";
foreach (k; v[0..$-1]) {
s = std.string.format("%s, %s", s, k);
}
s = std.string.format("%s, %s]", s, v[$-1]);
}
void testvector() {
// ...
foreach (index, ref value; v) {
value = index;
}
// ...
}
Hope that helps.
|
April 14, 2009 Re: Template classes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Spott Attachments: | On Tue, 14 Apr 2009 17:01:28 -0400, Andrew Spott <andrew.spott@gmail.com> wrote:
> So, the attached is supposed to be a class that creates a vector of any type (I would like it to only take numerical values (int, float, real, double, etc), however, I am ok with it taking others (not that I see why someone would use it that way).
>
> I tried to compile it with the following, but it won't compile. I don't really understand the errors I'm getting either.
>
> Can someone tell me what I'm doing wrong? If you need more information, let me know.
>
> -Andrew
>
> void testvector() {
> auto v = new Vector!(float)(3, 12.0);
> writefln(v.toString());
> int n = 0;
>
> while (n < n.size()) {
> v[n] = n;
> }
>
> writefln(v.toString());
>
> }
Try the attached (untested).
You might get some insight into how d should be written by looking at the changes.
BTW, if this is just an exercise fine, but your example is a completely redundant implementation of standard builtin arrays.
e.g., the following code does almost the same thing you are doing without requiring a new class:
void testvector() {
auto v = new float[3];
v[0..$] = 12.0;
writefln(v);
int n = 0;
while(n < v.length) { // bug in original code
v[n] = n;
n++; // bug in original code
}
writefln(v);
}
-Steve
|
April 14, 2009 Re: Template classes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Tue, 14 Apr 2009 17:33:29 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> e.g., the following code does almost the same thing you are doing without
> requiring a new class:
correction, the code does *exactly* the same thing you are doing.
-Steve
|
April 15, 2009 Re: Template classes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | yes, however there are going to be a few new classes that will be implemented in this (dot products, cross products, etc)
Thanks for the help.
-Andrew
Steven Schveighoffer Wrote:
> On Tue, 14 Apr 2009 17:33:29 -0400, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
>
> > e.g., the following code does almost the same thing you are doing without requiring a new class:
>
> correction, the code does *exactly* the same thing you are doing.
>
> -Steve
|
April 15, 2009 Re: Template classes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Spott | Andrew Spott:
> yes, however there are going to be a few new classes that will be implemented in this (dot products, cross products, etc)
You mean a few new methods.
Take a look at the 'this' of D2, it allows to create wrapper structs, so you can just add methods to the built-in arrays.
Bye,
bearophile
|
April 15, 2009 Re: Template classes | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | bearophile skrev:
> Andrew Spott:
>> yes, however there are going to be a few new classes that will be implemented in this (dot products, cross products, etc)
>
> You mean a few new methods.
>
> Take a look at the 'this' of D2, it allows to create wrapper structs, so you can just add methods to the built-in arrays.
>
> Bye,
> bearophile
Please elaborate on this. How does one do that?
/ab
|
April 15, 2009 Re: Template classes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Arild Boes | On Wed, Apr 15, 2009 at 12:13 PM, Arild Boes <aboesx@gmail.com> wrote:
>> Take a look at the 'this' of D2, it allows to create wrapper structs, so you can just add methods to the built-in arrays.
>>
>> Bye,
>> bearophile
>
> Please elaborate on this. How does one do that?
With the new, delicious "alias this."
struct Array(T)
{
T[] blah;
alias blah this; // woo!
void print()
{
writefln(blah);
}
}
void main()
{
Array!(int) x;
// anything not defined in Array will instead be looked up in the
'alias this' member
x.length = 5;
x[2] = 3;
x.print();
}
Though actually I'm not sure why bearophile suggested this, since even
in D1, you can define 'extension' methods for arrays and AAs by simply
declaring a function that takes an array or AA as its first parameter.
It's syntactic sugar for a normal function call. By taking advantage
of templates and IFTI you can make these methods work for all kinds of
arrays.
void print(T)(T[] arr)
{
writefln(arr);
}
void main()
{
int[] x;
x.length = 5;
x[2] = 3;
x.print(); // same as print(x);
}
This will work in D1 or D2.
|
April 15, 2009 Re: Template classes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley:
> Though actually I'm not sure why bearophile suggested this,
The original poster seems to want to add some methods to a standard array. With this you can give another module something that acts like an array that also has such methods, or replaces them. With the old way you also need to import the free functions into the other module...
Bye,
bearophile
|
April 16, 2009 Re: Template classes | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley skrev:
> On Wed, Apr 15, 2009 at 12:13 PM, Arild Boes <aboesx@gmail.com> wrote:
>
>>> Take a look at the 'this' of D2, it allows to create wrapper structs, so
>>> you can just add methods to the built-in arrays.
>>>
>>> Bye,
>>> bearophile
>> Please elaborate on this. How does one do that?
>
> With the new, delicious "alias this."
>
> struct Array(T)
> {
> T[] blah;
> alias blah this; // woo!
>
> void print()
> {
> writefln(blah);
> }
> }
>
> void main()
> {
> Array!(int) x;
> // anything not defined in Array will instead be looked up in the
> 'alias this' member
> x.length = 5;
> x[2] = 3;
> x.print();
> }
>
> Though actually I'm not sure why bearophile suggested this, since even
> in D1, you can define 'extension' methods for arrays and AAs by simply
> declaring a function that takes an array or AA as its first parameter.
> It's syntactic sugar for a normal function call. By taking advantage
> of templates and IFTI you can make these methods work for all kinds of
> arrays.
>
> void print(T)(T[] arr)
> {
> writefln(arr);
> }
>
> void main()
> {
> int[] x;
> x.length = 5;
> x[2] = 3;
> x.print(); // same as print(x);
> }
>
> This will work in D1 or D2.
I see. Thank you very much for that answer.
Actually the f-call syntactic sugar seems like a good way to keep core classes of any library very lean and mean, whilst maintaining the ability to expand the module without re-compiling the original library! (just import this guy, and the new functions will be available to you as if declared in the original type).
|
Copyright © 1999-2021 by the D Language Foundation