Thread overview
Getting around forward references in templates?
May 02, 2007
Tristam MacDonald
May 04, 2007
Tristam MacDonald
May 07, 2007
Stewart Gordon
May 07, 2007
Tristam MacDonald
May 02, 2007
So I have a setup like the following (simplified) example:

module A;

import B;

struct A(T)
{
	T x, y;

	void set(B o) {x = cast(T)o.a; y = cast(T)o.b;}
}

alias A!(float) Af;

//=========================

module B;

import A;

struct B
{
	float a, b;

	static B opCall(float x, float y) {B t; t.a = x; t.b = y; return t;}

	void set(Af o) {a = o.x; b = o.y;}
}

//=============================

import A;
import B;

int main()
{
	B b = B(1.0, 2.0);

	Af a;

	a.set(b);

	return 0;
}

//------------------------------

Now the compiler says:

B.d:12: Error: forward reference to 'A!(float)'
B.d:12: Error: Af is used as a type
B.d:12: Error: cannot have parameter of type void
B.d:12: Error: forward reference to 'A!(float)'
B.d:12: Error: Af is used as a type
B.d:12: Error: cannot have parameter of type void

Obviously this is a contrived example, but it is not uncommon to have a module containing a template which must import itself in a circular manner. Is there any way (easy or not) to get around this, other than passing a pointer to float* into A.set(B)?


May 04, 2007
So am I correct that it is impossible to forward reference a template instantiation? And if so, why?
May 07, 2007
"Tristam MacDonald" <swiftcoder@gmail.com> wrote in message news:f1f6ac$2uvc$1@digitalmars.com...
> So am I correct that it is impossible to forward reference a template instantiation? And if so, why?

Because the compiler has bugs in it.

http://d.puremagic.com/issues/show_bug.cgi?id=810

Generally, if you ever see the phrase "forward reference" in a compiler message, chances are it's a bug.

http://d.puremagic.com/issues/show_bug.cgi?id=340

Stewart. 

May 07, 2007
Interesting... So since I am using gdc, both compilers exhibit this bug. More to the point, has anyone come up with ways of dealing with this? From what I have tried, no source file containing a template specialisation can be imported by the file containing the template itself - even if the first file doesn't use the template.

Worth noting is that if I put both structs from my original example in the same file, the forward references work fine! So why are imports different?

A.d:

module A;

struct As(T)
{
	T x, y;

	void set(Bs o) {x = cast(T)o.a; y = cast(T)o.b;}
}

alias As!(float) Af;

struct Bs
{
	float a, b;

	static Bs opCall(float x, float y) {Bs t; t.a = x; t.b = y; return t;}

	void set(Af o) {a = o.x; b = o.y;}
}
 // No errors and compiles fine???

Stewart Gordon Wrote:
> "Tristam MacDonald" <swiftcoder@gmail.com> wrote in message news:f1f6ac$2uvc$1@digitalmars.com...
> > So am I correct that it is impossible to forward reference a template instantiation? And if so, why?
> 
> Because the compiler has bugs in it.
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=810
> 
> Generally, if you ever see the phrase "forward reference" in a compiler message, chances are it's a bug.
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=340
> 
> Stewart.