digitalmars.D.learn - A module comprehensive template-specialization
- Matthias Walter (39/39) Jun 27 2010 Hi list,
- Simen kjaeraas (33/35) Jun 27 2010 Template constraints[1] sounds like what you want.
- Matthias Walter (9/51) Jun 28 2010 The problem with constraints arises when I want to make an existing
- Justin Spahr-Summers (6/53) Jun 28 2010 I believe this is intended behavior, as it prevents template hijacking
- Matthias Walter (12/67) Jun 28 2010 I tried to do so in some variants but did not succeed unfortunately. If
- Rory McGuire (6/76) Jun 28 2010 I haven't looked at the boost stuff you mention but is it possible that ...
Hi list, I tried to write a traits class comparable to iterator_traits in C++ STL or graph_traits in Boost Graph Library in D 2.0, but failed to do so via template specialization which is put into different modules. Putting everything into one module interferes with extensibility. I tried the following: == Module a == | module a; | | template Base (T) | { | alias T Base; | } == Module b == | module b; | | import a; | | template Base(T: T*) | { | alias Base !(T) Base; | } == Main module == | | import a, b; | | int main(char[][] args) | { | alias Base !(int*) foo; | | return 0; | } The error message is: "bug.d(8): Error: template instance ambiguous template declaration b.Base(T : T*) and a.Base(T)" Can I handle this in another way (like making the template a conditional one)? best regards Matthias Walter
Jun 27 2010
Matthias Walter <xammy xammy.homelinux.net> wrote:Can I handle this in another way (like making the template a conditional one)?Template constraints[1] sounds like what you want. Basically, you want the following: == Module a == | module a; | | template Base (T) if (!is(T t : t*)) | { | alias T Base; | } == Module b == | module b; | | import a; | | template Base(T) if (is(T t : t*)) | { | alias Base !(T) Base; | } == Main module == | | import a, b; | | int main(char[][] args) | { | alias Base !(int*) foo; | | return 0; | } Not tested, ymmv. [1]: http://digitalmars.com/d/2.0/template.html#Constraint -- Simen
Jun 27 2010
On 06/28/2010 05:32 AM, Simen kjaeraas wrote:Matthias Walter <xammy xammy.homelinux.net> wrote:The problem with constraints arises when I want to make an existing class (who's code I cannot modify) match a Concept, in which case I would just add another template specialization for this class. Here I would have to add further conditions to the template constraints, which would also mean to modify a library. A prominent example for Boost Graph Library is the LEDA graph class, which can be enabled to be used by BGL by more or less just specializing the graph_traits template. Any further ideas?Can I handle this in another way (like making the template a conditional one)?Template constraints[1] sounds like what you want. Basically, you want the following: == Module a == | module a; | | template Base (T) if (!is(T t : t*)) | { | alias T Base; | } == Module b == | module b; | | import a; | | template Base(T) if (is(T t : t*)) | { | alias Base !(T) Base; | } == Main module == | | import a, b; | | int main(char[][] args) | { | alias Base !(int*) foo; | | return 0; | } Not tested, ymmv. [1]: http://digitalmars.com/d/2.0/template.html#Constraint
Jun 28 2010
On Sun, 27 Jun 2010 18:51:35 +0200, Matthias Walter <xammy xammy.homelinux.net> wrote:Hi list, I tried to write a traits class comparable to iterator_traits in C++ STL or graph_traits in Boost Graph Library in D 2.0, but failed to do so via template specialization which is put into different modules. Putting everything into one module interferes with extensibility. I tried the following: == Module a == | module a; | | template Base (T) | { | alias T Base; | } == Module b == | module b; | | import a; | | template Base(T: T*) | { | alias Base !(T) Base; | } == Main module == | | import a, b; | | int main(char[][] args) | { | alias Base !(int*) foo; | | return 0; | } The error message is: "bug.d(8): Error: template instance ambiguous template declaration b.Base(T : T*) and a.Base(T)" Can I handle this in another way (like making the template a conditional one)? best regards Matthias WalterI believe this is intended behavior, as it prevents template hijacking and the like. Using alias to import the two templates into the same scope might help, though I'm not sure exactly how it should be done. On another note, though, have you looked at __traits() and std.traits?
Jun 28 2010
On 06/28/2010 09:49 AM, Justin Spahr-Summers wrote:On Sun, 27 Jun 2010 18:51:35 +0200, Matthias Walter <xammy xammy.homelinux.net> wrote:I tried to do so in some variants but did not succeed unfortunately. If you have a precise idea, please let me know!Hi list, I tried to write a traits class comparable to iterator_traits in C++ STL or graph_traits in Boost Graph Library in D 2.0, but failed to do so via template specialization which is put into different modules. Putting everything into one module interferes with extensibility. I tried the following: == Module a == | module a; | | template Base (T) | { | alias T Base; | } == Module b == | module b; | | import a; | | template Base(T: T*) | { | alias Base !(T) Base; | } == Main module == | | import a, b; | | int main(char[][] args) | { | alias Base !(int*) foo; | | return 0; | } The error message is: "bug.d(8): Error: template instance ambiguous template declaration b.Base(T : T*) and a.Base(T)" Can I handle this in another way (like making the template a conditional one)? best regards Matthias WalterI believe this is intended behavior, as it prevents template hijacking and the like. Using alias to import the two templates into the same scope might help, though I'm not sure exactly how it should be done.On another note, though, have you looked at __traits() and std.traits?I looked at them but didn't find them helpful for this precise problem. The whole reason for doing this is to make it possible to make another existing class model the concept (i.e. have some aliases / typedefs done) of my library class without editing any of them. As I mentioned in my other response, a prominent example for Boost Graph Library is the LEDA graph class, which can be enabled to be used by BGL by more or less just specializing the graph_traits template. I'd like to have this kind of technique available, too. Any further suggestions?
Jun 28 2010
On Mon, 28 Jun 2010 11:09:13 +0200, Matthias Walter <xammy xammy.homelinux.net> wrote:On 06/28/2010 09:49 AM, Justin Spahr-Summers wrote:I haven't looked at the boost stuff you mention but is it possible that using alias this, solves a similar or the same problem? TDPL addresses the use of aliasing to bring multiple declarations into the same scope/module but it only uses actual functions not templates.On Sun, 27 Jun 2010 18:51:35 +0200, Matthias Walter <xammy xammy.homelinux.net> wrote:I tried to do so in some variants but did not succeed unfortunately. If you have a precise idea, please let me know!Hi list, I tried to write a traits class comparable to iterator_traits in C++ STL or graph_traits in Boost Graph Library in D 2.0, but failed to do so via template specialization which is put into different modules. Putting everything into one module interferes with extensibility. I tried the following: == Module a == | module a; | | template Base (T) | { | alias T Base; | } == Module b == | module b; | | import a; | | template Base(T: T*) | { | alias Base !(T) Base; | } == Main module == | | import a, b; | | int main(char[][] args) | { | alias Base !(int*) foo; | | return 0; | } The error message is: "bug.d(8): Error: template instance ambiguous template declaration b.Base(T : T*) and a.Base(T)" Can I handle this in another way (like making the template a conditional one)? best regards Matthias WalterI believe this is intended behavior, as it prevents template hijacking and the like. Using alias to import the two templates into the same scope might help, though I'm not sure exactly how it should be done.On another note, though, have you looked at __traits() and std.traits?I looked at them but didn't find them helpful for this precise problem. The whole reason for doing this is to make it possible to make another existing class model the concept (i.e. have some aliases / typedefs done) of my library class without editing any of them. As I mentioned in my other response, a prominent example for Boost Graph Library is the LEDA graph class, which can be enabled to be used by BGL by more or less just specializing the graph_traits template. I'd like to have this kind of technique available, too. Any further suggestions?
Jun 28 2010