digitalmars.D - Forward declarations of template specilizations.
- Ryan Bloomfield (62/62) Nov 14 2008 I have an interesting issue, that makes me curious on how D handles it.
- Christian Kamm (8/11) Nov 16 2008 You cannot spread out template specializations across modules. If you de...
- Bill Baxter (15/26) Nov 16 2008 I think what Ryan said there is the general approach you have to take.
- Ryan Bloomfield (6/40) Nov 16 2008 I think can understand why it works the way it does. ADL does sound a bi...
- Frits van Bommel (3/4) Nov 16 2008 Well, it's *not* a type, so that's understandable.
- Jarrett Billingsley (12/13) Nov 16 2008 You use an alias parameter instead of a type parameter.
- Jarrett Billingsley (3/14) Nov 16 2008 Do D2's overload sets solve this, or are those for functions only?
I have an interesting issue, that makes me curious on how D handles it.
consider the following:
======================
module List;
template NodeTraits(NodeType)
{
static NodeType getNext(NodeType v) { return v.next; }
}
class List(NodeType, Traits=NodeTraits!(NodeType))
{
private NodeType head;
NodeType next() { return Traits.getNext(head); }
}
======================
module main;
class Node {
Node myNext;
}
template NodeTraits(NodeType : C)
{
static NodeType getNext(NodeType v) { return v.myNext; }
}
main()
{
alias List!(Node) L;
L l = new L();
C next = l.next(); // error: no property 'next' for type 'main.Node'
}
==============================================
Templates are evaluated in the scope they are defined, which makes sense, but
when should the compiler check those definitions? It makes sense that given 2
modules, one module shouldn't be able to change the behavior of another module,
having said that, c++ does allow this, and it proves very useful in customizing
the behavior of library classes.
I noticed that if I change it to the following it works correctly(Traits
argument becomes an alias, and is passed in main):
======================
module List;
template NodeTraits(NodeType)
{
static NodeType getNext(NodeType v) { return v.next; }
}
class List(NodeType, alias Traits)
{
private NodeType head;
NodeType next() { return Traits.getNext(head); }
}
======================
module main;
class Node {
Node myNext;
}
template NodeTraits(NodeType : Node)
{
static NodeType getNext(NodeType v) { return v.myNext; }
}
main()
{
alias NodeTraits!(Node) Traits; // a template's alias arguments only
take a single identifier
alias List!(Node, Traits) L;
L l = new L();
C next = l.next(); // Successfully accesses l.myNext
}
==============================================
Does the evaluation of a template have to know only the scope it was
instantiated in? No forward declaration(of a module that imports it)?
Nov 14 2008
I have an interesting issue, that makes me curious on how D handles it. (Traits template code)You cannot spread out template specializations across modules. If you define template Trait(T : S); in a.d and template Trait(T : C); in b.d and try to use alias Trait!(S) sinst; in use.d, you'll get Error: a.Trait(T : S) at a.d(3) conflicts with b.Trait(T : C) at b.d(3) because the two Traits live in separate scopes. This makes C++ style trait templates just not work in D. Does anyone know an equivalent?
Nov 16 2008
On Sun, Nov 16, 2008 at 5:14 PM, Christian Kamm <kamm-incasoftware removethis.de> wrote:I think what Ryan said there is the general approach you have to take. Don't specialize the traits template, but rather pass in a whole new template as an alias parameter to the main template. This would be a good thing to add here: http://www.prowiki.org/wiki4d/wiki.cgi?PortingFromCxx Is there some canonical example of where you use specialized traits templates in C++? Or is this maybe a more general issue, like porting ADL code in C++. Not traits templates, but another ADL example is how you see IO done often in C++. With overloads for some common function like "write(Stream& o, ModuleSpecificType& val)". This pattern doesn't translate directly to D either. Suggestions? --bbI have an interesting issue, that makes me curious on how D handles it. (Traits template code)You cannot spread out template specializations across modules. If you define template Trait(T : S); in a.d and template Trait(T : C); in b.d and try to use alias Trait!(S) sinst; in use.d, you'll get Error: a.Trait(T : S) at a.d(3) conflicts with b.Trait(T : C) at b.d(3) because the two Traits live in separate scopes. This makes C++ style trait templates just not work in D. Does anyone know an equivalent?
Nov 16 2008
Bill Baxter Wrote:On Sun, Nov 16, 2008 at 5:14 PM, Christian Kamm <kamm-incasoftware removethis.de> wrote:I think can understand why it works the way it does. ADL does sound a bit too complex(being hard to understand it's side-effect) to add to D. Polymorphism could be used as an alternative(the library class uses an interface to interact with the data), but that requires run-time overhead, but necessary anyway if polymorphism is involved in the data type. If I change the Traits from a template into a class template makes it easier to pass(no alias argument), the major difference is that the traits must be passed whenever it is overridden. According to http://www.digitalmars.com/d/1.0/templates-revisited.html(under "Template Parameters") a template can be passed as a template argument. How does one do that? The compiler (gdc) give an error when I try to pass a template like a type(complains it isn't a type). RyanI think what Ryan said there is the general approach you have to take. Don't specialize the traits template, but rather pass in a whole new template as an alias parameter to the main template. This would be a good thing to add here: http://www.prowiki.org/wiki4d/wiki.cgi?PortingFromCxx Is there some canonical example of where you use specialized traits templates in C++? Or is this maybe a more general issue, like porting ADL code in C++. Not traits templates, but another ADL example is how you see IO done often in C++. With overloads for some common function like "write(Stream& o, ModuleSpecificType& val)". This pattern doesn't translate directly to D either. Suggestions? --bbI have an interesting issue, that makes me curious on how D handles it. (Traits template code)You cannot spread out template specializations across modules. If you define template Trait(T : S); in a.d and template Trait(T : C); in b.d and try to use alias Trait!(S) sinst; in use.d, you'll get Error: a.Trait(T : S) at a.d(3) conflicts with b.Trait(T : C) at b.d(3) because the two Traits live in separate scopes. This makes C++ style trait templates just not work in D. Does anyone know an equivalent?
Nov 16 2008
Ryan Bloomfield wrote:According to http://www.digitalmars.com/d/1.0/templates-revisited.html(under "Template Parameters") a template can be passed as a template argument. How does one do that? The compiler (gdc) give an error when I try to pass a template like a type(complains it isn't a type).Well, it's *not* a type, so that's understandable. It'll work as an alias parameter though.
Nov 16 2008
On Sun, Nov 16, 2008 at 3:52 PM, Ryan Bloomfield <_sir_maniacREMOVE_ME yahoo.com> wrote:According to http://www.digitalmars.com/d/1.0/templates-revisited.html(under "Template Parameters") a template can be passed as a template argument. How does one do that? The compiler (gdc) give an error when I try to pass a template like a type(complains it isn't a type).You use an alias parameter instead of a type parameter. template A(alias Foo) { alias Foo!(int) A; } template B(T) { T B; } alias A!(B) x; // same as declaring "int x"
Nov 16 2008
On Sun, Nov 16, 2008 at 3:14 AM, Christian Kamm <kamm-incasoftware removethis.de> wrote:Do D2's overload sets solve this, or are those for functions only?I have an interesting issue, that makes me curious on how D handles it. (Traits template code)You cannot spread out template specializations across modules. If you define template Trait(T : S); in a.d and template Trait(T : C); in b.d and try to use alias Trait!(S) sinst; in use.d, you'll get Error: a.Trait(T : S) at a.d(3) conflicts with b.Trait(T : C) at b.d(3) because the two Traits live in separate scopes. This makes C++ style trait templates just not work in D. Does anyone know an equivalent?
Nov 16 2008









Frits van Bommel <fvbommel REMwOVExCAPSs.nl> 