Thread overview | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 30, 2010 How to initialize static array member variable? | ||||
---|---|---|---|---|
| ||||
Hi,
I'm still playing around with DMD 2.049 and my Vector struct. This
struct Vector(alias N,T)
{
static immutable Vector X=Vector(1,0,0);
this(T[N] v ...) {
data=v;
}
T data[N];
};
alias Vector!(3,float) Vec3f;
gives
Error 1 Error: Slice operation this.data[] = cast(const(float[]))v cannot be evaluated at compile time main.d 6
I also tried simply
struct Vector(alias N,T)
{
static immutable Vector X=Vector(1,0,0);
this(T x,T y,T z) {
data[0]=x;
data[1]=y;
data[2]=z;
}
T data[N];
};
alias Vector!(3,float) Vec3f;
but that gives
Error 1 Error: Index assignment this.data[0u] = x is not yet supported in CTFE main.d 6
Error 2 Error: Index assignment this.data[1u] = y is not yet supported in CTFE main.d 7
Error 3 Error: Index assignment this.data[2u] = z is not yet supported in CTFE main.d 8
Any other ideas how to introduce such an "X" constant?
Thanks.
--
Sebastian Schuberth
|
September 30, 2010 Re: How to initialize static array member variable? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sebastian Schuberth | On Thu, Sep 30, 2010 at 21:14, Sebastian Schuberth <sschuberth@gmail.com> wrote: > Hi, > > I'm still playing around with DMD 2.049 and my Vector struct. This > > struct Vector(alias N,T) > { > static immutable Vector X=Vector(1,0,0); > > this(T[N] v ...) { > data=v; > } > > T data[N]; > }; To me, your constructor's signature is saying: "give me any number of T[N]", which I guess is not what you want. You want exactly N T's. Which gives the following constructor: this(U...)(U v) if (U.length <= N && is(CommonType!U : T)) { data = [v]; } I guess I'll have to explain this: U... is a bunch of values of any type. With the template constraint I just check that 1) there is the correct number of values (at most N) 2) they can all be changed into T's as for the = [v] part, it's just that throwing a tuple in an array constructor will make an array from the tuple. Btw, "alias N" is a bit dangerous: N could be any symbol. As you use it as a size, let's give it a size type: Vector(int N, T) or Vector(size_t N, T). Also, T data[N]; is using a C syntax. In D, the idiomatic syntax is T[N] data; And there is no need for a semicolon at the end of a struct definition: the compiler knows it ends there. Which gives us: import std.traits: CommonType; struct Vector(size_t N,T) { this(U...)(U v) if (U.length <= N && is(CommonType!U == T)) { data = [v]; } T[N] data; } > Any other ideas how to introduce such an "X" constant? It's doable, but it means modifying your struct a bit: instead of holding the values in an array, you can store them in a tuple. I'll see if anyone as another idea: I'm biased towards tuples. Philippe |
September 30, 2010 Re: How to initialize static array member variable? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sebastian Schuberth | On Thursday 30 September 2010 12:14:09 Sebastian Schuberth wrote:
> Hi,
>
> I'm still playing around with DMD 2.049 and my Vector struct. This
>
> struct Vector(alias N,T)
> {
> static immutable Vector X=Vector(1,0,0);
>
> this(T[N] v ...) {
> data=v;
> }
>
> T data[N];
> };
>
> alias Vector!(3,float) Vec3f;
>
> gives
>
> Error 1 Error: Slice operation this.data[] = cast(const(float[]))v
> cannot be evaluated at compile time main.d 6
>
> I also tried simply
>
> struct Vector(alias N,T)
> {
> static immutable Vector X=Vector(1,0,0);
>
> this(T x,T y,T z) {
> data[0]=x;
> data[1]=y;
> data[2]=z;
> }
>
> T data[N];
> };
>
> alias Vector!(3,float) Vec3f;
>
> but that gives
>
> Error 1 Error: Index assignment this.data[0u] = x is not yet supported
> in CTFE main.d 6
> Error 2 Error: Index assignment this.data[1u] = y is not yet supported
> in CTFE main.d 7
> Error 3 Error: Index assignment this.data[2u] = z is not yet supported
> in CTFE main.d 8
>
> Any other ideas how to introduce such an "X" constant?
>
> Thanks.
You could initialized it in a static constructor. e.g.
static this()
{
X = Vector(1, 0, 0);
}
By the way, it's a bit atypical in D at this point to declare constants in all caps - primarily because you often end up with so many in your code that it can get pretty ugly to have so many variables in all caps.
Also, assuming that you could initialize the variable at compile-time (which you obviously having trouble doing here), the typical way to declare such a constant is not to use static but rather enum. e.g.
enum x = Vector(1, 0, 0);
However, since you can't initialize this particular variable at compile-time as it stands, a static variable would be the correct way to go here.
Also, if you declare a variable immutable and initialize directly (as opposed to using a destructor), you don't have to include the type (just like you don't have to include the type for enum). Of course, since you need a static constructor here, it won't work here, but I thought that I'd let you know.
- Jonathan M Davis
|
September 30, 2010 Re: How to initialize static array member variable? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sebastian Schuberth | Sebastian Schuberth:
> struct Vector(alias N,T)
> {
> static immutable Vector X=Vector(1,0,0);
>
> this(T[N] v ...) {
> data=v;
> }
>
> T data[N];
> };
>
> alias Vector!(3,float) Vec3f;
This seems to work:
struct Vector(int N, T) {
static immutable Vector x;
static this() {
x = Vector(1, 0, 0);
}
this(T[N] v...) {
data = v;
}
T[N] data;
}
alias Vector!(3,float) Vec3f;
void main() {
auto v = Vec3f(1,2,3);
v = v.x;
assert(v.data[0] == 1.0);
}
Your code doesn't work because type safe variadic functions can't be used at compile time yet :-) It's a limitation that I think Don will eventually remove.
Bye,
bearophile
|
September 30, 2010 Re: How to initialize static array member variable? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | Philippe Sigaud:
> It's doable, but it means modifying your struct a bit: instead of holding the values in an array, you can store them in a tuple. I'll see if anyone as another idea: I'm biased towards tuples.
Please, be gentle with the D newbie, don't burn his brain :-) You can't learn a big part of D2 in one day.
Bye,
bearophile
|
September 30, 2010 Re: How to initialize static array member variable? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sebastian Schuberth | > I also tried simply > > struct Vector(alias N,T) > { > static immutable Vector X=Vector(1,0,0); > > this(T x,T y,T z) { > data[0]=x; > data[1]=y; > data[2]=z; > } > > T data[N]; > }; This sort of constructor shouldn't be necessary since an implicit one will be generated. You could also try "alias data this;" to make the vector usable like an array. Here's a basic D2 fixed-size vector implementation for you to study: http://sfml.svn.sourceforge.net/viewvc/sfml/branches/sfml2/DSFML/import/dsfml/system/vector.d?view=markup |
September 30, 2010 Re: How to initialize static array member variable? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Trass3r | On Thu, Sep 30, 2010 at 23:10, Trass3r <un@known.com> wrote:
> This sort of constructor shouldn't be necessary since an implicit one will be generated.
Will it convert N T's into a T[N]?
|
September 30, 2010 Re: How to initialize static array member variable? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Thu, Sep 30, 2010 at 22:32, bearophile <bearophileHUGS@lycos.com> wrote:
> Philippe Sigaud:
>
>> It's doable, but it means modifying your struct a bit: instead of holding the values in an array, you can store them in a tuple. I'll see if anyone as another idea: I'm biased towards tuples.
>
> Please, be gentle with the D newbie, don't burn his brain :-) You can't learn a big part of D2 in one day.
Well, I did say I was biased :-) So much so, in fact, that didn't see
at first he was using an array.
I still wonder how the constructor works: how can T[N]v... accept 1,2,3?
|
September 30, 2010 Re: How to initialize static array member variable? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | > Will it convert N T's into a T[N]?
Ah wait, yeah, he uses an array.
What I mentioned works only if you have a struct with members x, y, z, ...
|
October 01, 2010 Re: How to initialize static array member variable? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | On 30.09.2010 22:01, Philippe Sigaud wrote: > To me, your constructor's signature is saying: "give me any number of > T[N]", which I guess is not what you want. You want exactly N T's. You're right, I want exactly N T's, but from reading the section about "Typesafe Variadic Functions" at [1], I thought I'm doing exactly that. The example "For static arrays" has a comment which says for a declaration like int sum(int[3] ar ...) this return sum(2, 3); // error, need 3 values for array would not work, so I thought "...", if following a statically sized array, is a special syntax to allow the array to be initialized from exactly N scalar values. In fact, I checked that with my code auto v=Vec3f(1,0,0); compiles, but auto v=Vec3f(1,0); auto v=Vec3f(1,0,0,0); auto v=Vec3f([1,0,0],[1,0,0]); do not compile, just as desired. So I thought I'm doing the right thing :-) > Which gives the following constructor: > > this(U...)(U v) if (U.length<= N&& is(CommonType!U : T)) > { > data = [v]; > } Well, this makes sense, thank you. I'm just wondering if my solution is any less safe? > Btw, "alias N" is a bit dangerous: N could be any symbol. As you use > it as a size, let's give it a size type: Vector(int N, T) or > Vector(size_t N, T). > Also, T data[N]; is using a C syntax. In D, the idiomatic syntax is T[N] data; > And there is no need for a semicolon at the end of a struct > definition: the compiler knows it ends there. Thanks for all the hints! > It's doable, but it means modifying your struct a bit: instead of > holding the values in an array, you can store them in a tuple. > I'll see if anyone as another idea: I'm biased towards tuples. With tuples, would it still be that sizeof(Vector)==sizeof(T)*N? [1] http://www.digitalmars.com/d/2.0/function.html -- Sebastian Schuberth |
Copyright © 1999-2021 by the D Language Foundation