Array initialization with Struct templates

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 30 22:47:31 PDT 2015


On 08/30/2015 10:38 PM, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Monday, August 31, 2015 04:57:05 WhatMeWorry via Digitalmars-d-learn wrote:
>>
>> This seemingly trivial array initialization has caused me hours
>> of grief.
>>
>> enum Purpose { POSITIONAL, COLOR_ONLY, COLOR_AND_ALPHA,
>> GENERIC_TRIPLE, GENERIC_QUAD }
>> Purpose purpose;
>>
>> struct Chameleon(T, Purpose p)  // template
>> {
>>       static if (is (p == POSITIONAL)) {
>>           T  x, y, z;
>>       } else static if (is (p == COLOR_ONLY)) {
>>           T  r, g, b;
>>       } else static if (is (p == COLOR_AND_ALPHA)) {
>>           T  r, g, b, a;
>>       }  else static if (is (p == GENERIC_TRIPLE)) {
>>           T  a, b, c;
>>       } else static if (is (p == GENERIC_QUAD)) {
>>           T  a, b, c, d;
>>       }
>> };
>>
>> struct VertexData
>> {
>>       Chameleon!(float, purpose.POSITIONAL)  position;
>>       Chameleon!(float, purpose.COLOR_ONLY)  color;
>> }
>>
>> alias Vert = VertexData;
>>
>> VertexData[] vertices =
>> [
>>       Vert(1.0, 1.0, 1.0, 0.0, 0.0, 0.0)  // compiler error here
>> ];
>>
>> I keep getting:
>>
>> Error: cannot implicitly convert expression (1.00000) of type
>> double to Chameleon!(double, cast(Purpose)0)
>>
>> I even tried  Vert(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f)
>>
>> but it has the exact same error.  Any ideas?  Thanks in advance.
>
> VertexData doesn't have a constructor that takes 6 doubles or 6 floats. It
> has a compiler-generated constructor that's equivalent to
>
>
> this(Chameleon!(float, purpose.POSITIONAL) position,
>       Chameleon!(float, purpose.COLOR_ONLY) color)
> {
>      this.position = position;
>      this.color = color;
> }
>
> So, you're going to need to pass it a Chameleon!(float, purpose.POSITIONAL)
> and a Chameleon!(float, purpose.COLOR_ONLY color), not 6 doubles - either
> that, or you're going to need to declare a constructor for VertexData which
> takes 6 doubles or floats and converts them to what's require to assign to
> its member variables.
>
> - Jonathan M Davis
>

Additionally, the OP uses the is expression which compares the equality 
of types. However, 'Purpose p' is a value template parameter. A simple 
== comparison works:

enum Purpose { POSITIONAL, COLOR_ONLY, COLOR_AND_ALPHA, GENERIC_TRIPLE, 
GENERIC_QUAD }
Purpose purpose;

struct Chameleon(T, Purpose p)  // template
{
     static if (p == Purpose.POSITIONAL) {  // <-- NOT is expression
         T  x, y, z;
     } else static if (p == Purpose.COLOR_ONLY) {
         T  r, g, b;
     } else static if (p == Purpose.COLOR_AND_ALPHA) {
         T  r, g, b, a;
     }  else static if (p == Purpose.GENERIC_TRIPLE) {
         T  a, b, c;
     } else static if (p == Purpose.GENERIC_QUAD) {
         T  a, b, c, d;
     }
};

struct VertexData
{
     Chameleon!(float, purpose.POSITIONAL)  position;
     Chameleon!(float, purpose.COLOR_ONLY)  color;
}

alias Vert = VertexData;

VertexData[] vertices =
[
     Vert(Chameleon!(float, purpose.POSITIONAL)(1.0f, 1.0f, 1.0f),
          Chameleon!(float, purpose.COLOR_ONLY)(0.0, 0.0, 0.0))
];

void main()
{}





More information about the Digitalmars-d-learn mailing list