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