digitalmars.D.learn - Templated Interfaces?
- Benji Smith <dlanguage benjismith.net> Aug 24 2008
- Ary Borenszweig <ary esperanto.org.ar> Aug 24 2008
- Benji Smith <dlanguage benjismith.net> Aug 24 2008
- Benji Smith <dlanguage benjismith.net> Aug 24 2008
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Aug 24 2008
- Benji Smith <dlanguage benjismith.net> Aug 24 2008
- Ary Borenszweig <ary esperanto.org.ar> Aug 25 2008
- Sergey Gromov <snake.scaly gmail.com> Aug 25 2008
- Ary Borenszweig <ary esperanto.org.ar> Aug 25 2008
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Aug 26 2008
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Aug 26 2008
- Ary Borenszweig <ary esperanto.org.ar> Aug 26 2008
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Aug 27 2008
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Aug 25 2008
- Bruno Medeiros <brunodomedeiros+spam com.gmail> Sep 08 2008
- Jason House <jason.james.house gmail.com> Aug 24 2008
- "Jarrett Billingsley" <kb3ctd2 yahoo.com> Aug 24 2008
- Benji Smith <dlanguage benjismith.net> Aug 24 2008
- "Simen Kjaeraas" <simen.kjaras gmail.com> Aug 24 2008
I've been trying to create a templated interface, and can't figure out
what I'm doing wrong. Here's the basic example:
interface I(T) {
public T x();
}
class C(T) : I(T) {
private T value;
public this(T val) { this.value = val; }
public T x() { return value; }
}
void main() {
I!(char) c = new C!(char)('a');
char value = c.x();
}
I've tried many many slight variations of this, to try to satisfy the
compiler, but it always rejects the code, usually by saying something
like "Interface I used as a type".
Of course! That's because interface I *is* a type.
What am I doing wrong?
--benji
Aug 24 2008
Benji Smith a écrit :I've been trying to create a templated interface, and can't figure out what I'm doing wrong. Here's the basic example: interface I(T) { public T x(); } class C(T) : I(T) {
class C(T) : I!(T) {
Aug 24 2008
Ary Borenszweig wrote:Benji Smith a écrit :I've been trying to create a templated interface, and can't figure out what I'm doing wrong. Here's the basic example: interface I(T) { public T x(); } class C(T) : I(T) {
class C(T) : I!(T) {
Very nice! Thanks! Now let's say I want to create an array of those interface instances: interface I(T) { public T x(); } class C(T) : I!(T) { private T value; public this(T val) { this.value = val; } public T x() { return value; } } void main() { I!(char)[] array = new I!(char)[]; array ~ new C!(char)('a'); array ~ new C!(char)('b'); array ~ new C!(char)('c'); char value = array[0].x(); } Now the compiler is complaining about the line where I create the array. It says "Error: new can only create structs, dynamic arrays or class objects, not I[]'s" Obviously, I'm trying to create a dynamic array of interface instances, so I'm not sure what I'm doing wrong. Thanks! --benji
Aug 24 2008
Simen Kjaeraas wrote:You do not need to initialize the the array with the "new I!(char)[]". Just use I!(char)[] array; array ~= new C!(char)('a'); ... char value = array[0].x();
Gotcha. Coming from Java, it's hard getting used to which types require a 'new' and which ones don't. I find the array types especially confusing. Thanks for your help! --benji
Aug 24 2008
"Benji Smith" <dlanguage benjismith.net> wrote in message news:g8sih3$7h4$1 digitalmars.com...Simen Kjaeraas wrote:You do not need to initialize the the array with the "new I!(char)[]". Just use I!(char)[] array; array ~= new C!(char)('a'); ... char value = array[0].x();
Gotcha. Coming from Java, it's hard getting used to which types require a 'new' and which ones don't. I find the array types especially confusing. Thanks for your help! --benji
Well arrays work _almost_ the same way as in Java, the only difference being that they can change their size. You can either do auto array = new I!(char)[3]; array[0] = .. array[1] = .. array[2] = .. Or just declare it and append stuff. The former will be faster since you'll only do 1 memory allocation instead of n (although the implementation does over-allocate for arrays so that appending is faster, you may not want to depend on that for performance-critical code).
Aug 24 2008
Jarrett Billingsley wrote:Well arrays work _almost_ the same way as in Java, the only difference being that they can change their size. You can either do auto array = new I!(char)[3]; array[0] = .. array[1] = .. array[2] = .. Or just declare it and append stuff. The former will be faster since you'll only do 1 memory allocation instead of n (although the implementation does over-allocate for arrays so that appending is faster, you may not want to depend on that for performance-critical code).
Huh. I thought that, by putting an integer literal into the array declaration, it'd be declared as a static array rather than a dynamic array. --benji
Aug 24 2008
Benji Smith a écrit :Jarrett Billingsley wrote:Well arrays work _almost_ the same way as in Java, the only difference being that they can change their size. You can either do auto array = new I!(char)[3]; array[0] = .. array[1] = .. array[2] = .. Or just declare it and append stuff. The former will be faster since you'll only do 1 memory allocation instead of n (although the implementation does over-allocate for arrays so that appending is faster, you may not want to depend on that for performance-critical code).
Huh. I thought that, by putting an integer literal into the array declaration, it'd be declared as a static array rather than a dynamic array.
If you put an integer into the array declaration, it *is* declared as a static array. Static array: ------------- auto array = new I!(char)[3]; - array is of type I!(char)[3] (static array) - you cannot append using ~ - you can assign or access using indices - you can initialize it like that or using an array literal Dynamic array: -------------- I!(char)[] array; - array is of type I!(char)[] (dynamic array) - you can append using ~ - you can assign or access using indices - you can initialize it using an array literal
Aug 25 2008
Ary Borenszweig <ary esperanto.org.ar> wrote:If you put an integer into the array declaration, it *is* declared as a static array. Static array: ------------- auto array = new I!(char)[3]; - array is of type I!(char)[3] (static array) - you cannot append using ~ - you can assign or access using indices - you can initialize it like that or using an array literal
import std.stdio; void main() { auto a = new int[3]; writeln(typeof(a).stringof); } prints "int[]". new expression *always* produces a dynamic array. -- SnakE
Aug 25 2008
Sergey Gromov a écrit :Ary Borenszweig <ary esperanto.org.ar> wrote:If you put an integer into the array declaration, it *is* declared as a static array. Static array: ------------- auto array = new I!(char)[3]; - array is of type I!(char)[3] (static array) - you cannot append using ~ - you can assign or access using indices - you can initialize it like that or using an array literal
import std.stdio; void main() { auto a = new int[3]; writeln(typeof(a).stringof); } prints "int[]". new expression *always* produces a dynamic array.
Ouch. I first wrote I!(char)[3] array = new I!(char)[3]; which compiles, and makes array a static array (you can't append to it). Then, for simplicity, I changed the type to auto... it seems new makes a dynamic array, but then it is implicitly converted to a static one, right?
Aug 25 2008
"Ary Borenszweig" <ary esperanto.org.ar> wrote in message news:g8vp2l$11nf$1 digitalmars.com...Ouch. I first wrote I!(char)[3] array = new I!(char)[3]; which compiles, and makes array a static array (you can't append to it). Then, for simplicity, I changed the type to auto... it seems new makes a dynamic array, but then it is implicitly converted to a static one, right?
No. When you write auto x = Y; it is identical to writing typeof(Y) x = Y; In this case, typeof(new I!(char)[3]) is I!(char)[]. A dynamic array.
Aug 26 2008
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:g911lg$ja5$1 digitalmars.com..."Ary Borenszweig" <ary esperanto.org.ar> wrote in message news:g8vp2l$11nf$1 digitalmars.com...Ouch. I first wrote I!(char)[3] array = new I!(char)[3]; which compiles, and makes array a static array (you can't append to it). Then, for simplicity, I changed the type to auto... it seems new makes a dynamic array, but then it is implicitly converted to a static one, right?
No. When you write auto x = Y; it is identical to writing typeof(Y) x = Y; In this case, typeof(new I!(char)[3]) is I!(char)[]. A dynamic array.
Unless you meant in the non-auto case? In which case I'm kind of surprised the compiler allows it since it normally does not allow you to reassign static arrays.
Aug 26 2008
Jarrett Billingsley a écrit :"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:g911lg$ja5$1 digitalmars.com..."Ary Borenszweig" <ary esperanto.org.ar> wrote in message news:g8vp2l$11nf$1 digitalmars.com...Ouch. I first wrote I!(char)[3] array = new I!(char)[3]; which compiles, and makes array a static array (you can't append to it). Then, for simplicity, I changed the type to auto... it seems new makes a dynamic array, but then it is implicitly converted to a static one, right?
auto x = Y; it is identical to writing typeof(Y) x = Y; In this case, typeof(new I!(char)[3]) is I!(char)[]. A dynamic array.
Unless you meant in the non-auto case? In which case I'm kind of surprised the compiler allows it since it normally does not allow you to reassign static arrays.
Exactly, I meant in the non-auto case. What's going on there?
Aug 26 2008
"Ary Borenszweig" <ary esperanto.org.ar> wrote in message news:g92a1n$a9p$1 digitalmars.com...Jarrett Billingsley a écrit :"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:g911lg$ja5$1 digitalmars.com..."Ary Borenszweig" <ary esperanto.org.ar> wrote in message news:g8vp2l$11nf$1 digitalmars.com...Ouch. I first wrote I!(char)[3] array = new I!(char)[3]; which compiles, and makes array a static array (you can't append to it). Then, for simplicity, I changed the type to auto... it seems new makes a dynamic array, but then it is implicitly converted to a static one, right?
auto x = Y; it is identical to writing typeof(Y) x = Y; In this case, typeof(new I!(char)[3]) is I!(char)[]. A dynamic array.
Unless you meant in the non-auto case? In which case I'm kind of surprised the compiler allows it since it normally does not allow you to reassign static arrays.
Exactly, I meant in the non-auto case. What's going on there?
OK, I just tried it and stepped through and.. what it seems to do is it allocates an int[] of length 3 on the heap, then slice-copies it into the stack-allocated static array. No reference to the array on the heap is kept. Weird.
Aug 27 2008
"Ary Borenszweig" <ary esperanto.org.ar> wrote in message news:g8u542$b39$1 digitalmars.com...Static array: ------------- auto array = new I!(char)[3]; - array is of type I!(char)[3] (static array) - you cannot append using ~ - you can assign or access using indices - you can initialize it like that or using an array literal
No, new I!(char)[3] is syntactic sugar for new I!(char)[](3) and allocates a 3-element I!(char)[]. Fun fact: it is actually impossible within the syntax of D to allocate a static array on the heap. Not really surprising given the horrible treatment of static arrays in general.
Aug 25 2008
Jarrett Billingsley wrote:"Benji Smith" <dlanguage benjismith.net> wrote in message news:g8sih3$7h4$1 digitalmars.com...Simen Kjaeraas wrote:You do not need to initialize the the array with the "new I!(char)[]". Just use I!(char)[] array; array ~= new C!(char)('a'); ... char value = array[0].x();
Coming from Java, it's hard getting used to which types require a 'new' and which ones don't. I find the array types especially confusing. Thanks for your help! --benji
Well arrays work _almost_ the same way as in Java, the only difference being that they can change their size.
Also, Java's arrays are Object's, D's arrays are not. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Sep 08 2008
Simen Kjaeraas wrote:On Sun, 24 Aug 2008 22:20:46 +0200, Benji Smith <dlanguage benjismith.net> wrote:Ary Borenszweig wrote:Benji Smith a écrit :I've been trying to create a templated interface, and can't figure out what I'm doing wrong. Here's the basic example: interface I(T) { public T x(); } class C(T) : I(T) {
Very nice! Thanks! Now let's say I want to create an array of those interface instances: interface I(T) { public T x(); } class C(T) : I!(T) { private T value; public this(T val) { this.value = val; } public T x() { return value; } } void main() { I!(char)[] array = new I!(char)[]; array ~ new C!(char)('a'); array ~ new C!(char)('b'); array ~ new C!(char)('c'); char value = array[0].x(); } Now the compiler is complaining about the line where I create the array. It says "Error: new can only create structs, dynamic arrays or class objects, not I[]'s" Obviously, I'm trying to create a dynamic array of interface instances, so I'm not sure what I'm doing wrong. Thanks! --benji
You do not need to initialize the the array with the "new I!(char)[]". Just use I!(char)[] array; array ~= new C!(char)('a'); ... char value = array[0].x();
whoa, that's a bad idea! You can not implicitly cast back and forth between interfaces and classes that implement those interfaces; the underlying pointer is not the same. There was a big discussion about this fairly recently on one of the D mailing lists...
Aug 24 2008
"Jason House" <jason.james.house gmail.com> wrote in message news:g8sioq$6ul$1 digitalmars.com...whoa, that's a bad idea! You can not implicitly cast back and forth between interfaces and classes that implement those interfaces; the underlying pointer is not the same. There was a big discussion about this fairly recently on one of the D mailing lists...
No, what he's doing is OK. The trouble only occurs when you try to cast *the array* up or down the inheritance hierarchy.
Aug 24 2008
Jarrett Billingsley wrote:"Jason House" <jason.james.house gmail.com> wrote in message news:g8sioq$6ul$1 digitalmars.com...whoa, that's a bad idea! You can not implicitly cast back and forth between interfaces and classes that implement those interfaces; the underlying pointer is not the same. There was a big discussion about this fairly recently on one of the D mailing lists...
No, what he's doing is OK. The trouble only occurs when you try to cast *the array* up or down the inheritance hierarchy.
Yeah, with the code I'm currently working on, once the objects are in the array, I never again care what the specific class is for each instance, since I'll only be calling the interface methods. --benji
Aug 24 2008
On Sun, 24 Aug 2008 22:20:46 +0200, Benji Smith <dlanguage benjismith.net> wrote:Ary Borenszweig wrote:Benji Smith a écrit :I've been trying to create a templated interface, and can't figure out what I'm doing wrong. Here's the basic example: interface I(T) { public T x(); } class C(T) : I(T) {
Very nice! Thanks! Now let's say I want to create an array of those interface instances: interface I(T) { public T x(); } class C(T) : I!(T) { private T value; public this(T val) { this.value = val; } public T x() { return value; } } void main() { I!(char)[] array = new I!(char)[]; array ~ new C!(char)('a'); array ~ new C!(char)('b'); array ~ new C!(char)('c'); char value = array[0].x(); } Now the compiler is complaining about the line where I create the array. It says "Error: new can only create structs, dynamic arrays or class objects, not I[]'s" Obviously, I'm trying to create a dynamic array of interface instances, so I'm not sure what I'm doing wrong. Thanks! --benji
You do not need to initialize the the array with the "new I!(char)[]". Just use I!(char)[] array; array ~= new C!(char)('a'); ... char value = array[0].x(); -- Simen
Aug 24 2008









"Jarrett Billingsley" <kb3ctd2 yahoo.com> 