Thread overview
template struct question
Feb 12
monkyyy
Feb 14
bkoie
February 12
void main()
{

struct HexBoard(F,I)
{
    this(F d, I r, I c) {}
    //void displayHexBoard(HexBoard!(F,I) h) {}  // this compiles fine!
}

void displayHexBoard(HexBoard!(F,I) h) {}  // error undefined identifier F and I


auto h1 = HexBoard!(float,uint)(.25, 3, 7);
auto h2 = HexBoard!(double,int)(.3, 5, 5);

}


Is there any clever way to move the method outside of a templated block structure?  Or is this as good as it gets.

I tried
// Explicit instantiation for 'int' type
//int add!(int, int);
void displayHexBoardData(HexBoard2!(float,uint) h);  // declaration

but that just returns
Error: declaration `displayHexBoard` is already defined
onlineapp.d(10):        `function` `displayHexBoard` is defined here


February 12
On 2/12/25 12:55 PM, WhatMeWorry wrote:

> struct HexBoard(F,I)
> {
>      this(F d, I r, I c) {}
>      //void displayHexBoard(HexBoard!(F,I) h) {}  // this compiles fine!
> }
>
> void displayHexBoard(HexBoard!(F,I) h) {}  // error undefined identifier
> F and I

Would isInstanceOf be useful? (Which is actually optional.) It necessitated two aliases in the struct:

void main()
{
    struct HexBoard(F, I)
    {
        alias Float = F;
        alias Int = I;

        this(F d, I r, I c) {}
    }

    import std.traits : isInstanceOf;
    void displayHexBoard(HB)(HB h)
        if (isInstanceOf!(HexBoard, HB))
    {
        pragma(msg, "The types are ", HB.Float, " and ", HB.Int);
    }

    auto h1 = HexBoard!(float,uint)(.25, 3, 7);
    displayHexBoard(h1);
}

Ali

February 12

On Wednesday, 12 February 2025 at 20:55:14 UTC, WhatMeWorry wrote:

>
void main()
{

struct HexBoard(F,I)
{
    this(F d, I r, I c) {}
    //void displayHexBoard(HexBoard!(F,I) h) {}  // this compiles fine!
}

void displayHexBoard(HexBoard!(F,I) h) {}  // error undefined identifier F and I


auto h1 = HexBoard!(float,uint)(.25, 3, 7);
auto h2 = HexBoard!(double,int)(.3, 5, 5);

}


Is there any clever way to move the method outside of a templated block structure?  Or is this as good as it gets.

I tried
// Explicit instantiation for 'int' type
//int add!(int, int);
void displayHexBoardData(HexBoard2!(float,uint) h);  // declaration

but that just returns
Error: declaration `displayHexBoard` is already defined
onlineapp.d(10):        `function` `displayHexBoard` is defined here
struct foo(T){}
void bar(T)(foo!T){}
unittest{
	bar(foo!int());
	bar(foo!float());
}

it can be inferred at the call site, but template arguments must still be declared

February 13

On Wednesday, 12 February 2025 at 20:55:14 UTC, WhatMeWorry wrote:

>
void main()
{

struct HexBoard(F,I)
{
    this(F d, I r, I c) {}
    //void displayHexBoard(HexBoard!(F,I) h) {}  // this compiles fine!
}

void displayHexBoard(HexBoard!(F,I) h) {}  // error undefined identifier F and I


auto h1 = HexBoard!(float,uint)(.25, 3, 7);
auto h2 = HexBoard!(double,int)(.3, 5, 5);

}

Is there any clever way to move the method outside of a templated block structure? Or is this as good as it gets.

The problem is that the compiler doesn't know what F and I are. They are placeholders, but you didn't give them a definition.

void displayHexBoard(F, I)(HexBoard!(F,I) h) {}

-Steve

February 14

On Wednesday, 12 February 2025 at 20:55:14 UTC, WhatMeWorry wrote:

>
void main()
{

struct HexBoard(F,I)
{
    this(F d, I r, I c) {}
    //void displayHexBoard(HexBoard!(F,I) h) {}  // this compiles fine!
}

void displayHexBoard(HexBoard!(F,I) h) {}  // error undefined identifier F and I


auto h1 = HexBoard!(float,uint)(.25, 3, 7);
auto h2 = HexBoard!(double,int)(.3, 5, 5);

}


Is there any clever way to move the method outside of a templated block structure?  Or is this as good as it gets.

I tried
// Explicit instantiation for 'int' type
//int add!(int, int);
void displayHexBoardData(HexBoard2!(float,uint) h);  // declaration

but that just returns
Error: declaration `displayHexBoard` is already defined
onlineapp.d(10):        `function` `displayHexBoard` is defined here
import std.stdio;

struct Foo(T, L) { T t; L l; }
void display(T, L)(Foo!(T, L) f) { f.writeln; }

alias FooIntD = Foo!(int, double);
void main() { auto f = FooIntD(10, 20.3); f.display; }
February 14

Just wanted to thank everybody for their suggestions. Ali's code provided the breakthrough:

import std.stdio;
void main()
{

struct HexBoard(F,I)
{
    this(F d, I r, I c) { diameter = d; rows = r; cols = c; }
    F diameter;
    I rows;
    I cols;
}

void displayHexBoard(HB)(HB h) {
    writeln(typeof(h.diameter).stringof);
    writeln(typeof(h.rows).stringof);
}

auto h1 = HexBoard!(float,uint)(.25, 3, 7);
auto h2 = HexBoard!(double,int)(.3, 5, 5);

displayHexBoard(h1);
displayHexBoard(h2);
}

which returned

float
uint
double
int

My problem was with the definition of void displayHexBoard(HB)(HB h) {} definition.

I kept futzing around with trying to insert HexBoard(F,I) into where HB is. It is incredibly elegant how D can take h1 or h2 and instantiate the template HB.