digitalmars.D.learn - Template specialization using traits?
- Shriramana Sharma (14/14) Dec 21 2015 Hello. I want to define a template specialization using traits:
- rumbu (5/18) Dec 21 2015 void func(T)(T t) if(!isIntegral!T) { writeln(1); }
- Jonathan M Davis via Digitalmars-d-learn (21/33) Dec 21 2015 In D, each template constraint must match exactly once. A template with ...
- Jonathan M Davis (12/24) Dec 21 2015 Alternatively, you can use static if, though you're only dealing
- tcak (15/41) Dec 21 2015 Another alternative is:
- Shriramana Sharma (7/9) Dec 21 2015 But if we wanted to deprecate one of the alternatives, then we necessary...
- Jonathan M Davis via Digitalmars-d-learn (9/16) Dec 21 2015 Yes. Symbols get deprecated, not the internals of functions. So, you nee...
Hello. I want to define a template specialization using traits: import std.stdio, std.traits; void func(T)(T t) { writeln(1); } void func(T)(T t) if(isIntegral!T) { writeln(2); } void main() { func(1); } But I'm getting an error saying that the called function matches both. If it were a single type, I know I have to put the specialization as in: void func(T: int)(T t) { writeln(2); } and that works, but how to make it more generic than that? --
Dec 21 2015
On Monday, 21 December 2015 at 09:44:20 UTC, Shriramana Sharma wrote:Hello. I want to define a template specialization using traits: import std.stdio, std.traits; void func(T)(T t) { writeln(1); } void func(T)(T t) if(isIntegral!T) { writeln(2); } void main() { func(1); } But I'm getting an error saying that the called function matches both. If it were a single type, I know I have to put the specialization as in: void func(T: int)(T t) { writeln(2); } and that works, but how to make it more generic than that?void func(T)(T t) if(!isIntegral!T) { writeln(1); } void func(T)(T t) if(isIntegral!T) { writeln(2); } :)
Dec 21 2015
On Monday, December 21, 2015 15:14:20 Shriramana Sharma via Digitalmars-d-learn wrote:Hello. I want to define a template specialization using traits: import std.stdio, std.traits; void func(T)(T t) { writeln(1); } void func(T)(T t) if(isIntegral!T) { writeln(2); } void main() { func(1); } But I'm getting an error saying that the called function matches both. If it were a single type, I know I have to put the specialization as in: void func(T: int)(T t) { writeln(2); } and that works, but how to make it more generic than that?In D, each template constraint must match exactly once. A template with no template constraint is the same as having a template constraint that's always true. So, you need to alter your template constraints so that for a given template argument, exactly one template constraint is true. There really isn't such a thing as a specialization when dealing with template constraints. Using : like in your second example is the only kind of template specialization that we have. For your example to work with template constraints, the most straightforward solution would be void func(T)(T t) if(!isIntegral!T) { writeln(1); } void func(T)(T t) if(isIntegral!T) { writeln(2); } - Jonathan M Davis
Dec 21 2015
On Monday, 21 December 2015 at 11:07:16 UTC, Jonathan M Davis wrote:For your example to work with template constraints, the most straightforward solution would be void func(T)(T t) if(!isIntegral!T) { writeln(1); } void func(T)(T t) if(isIntegral!T) { writeln(2); }Alternatively, you can use static if, though you're only dealing with one template in that case. e.g. void func(T)(T t) { static if(isIntegral!T) writeln(2); else writeln(1); } - Jonathan M Davis
Dec 21 2015
On Monday, 21 December 2015 at 11:12:10 UTC, Jonathan M Davis wrote:On Monday, 21 December 2015 at 11:07:16 UTC, Jonathan M Davis wrote:Another alternative is: template func(T){ static if( isIntegral!T ){ void func(T t){ writeln( 2 ); } } else{ void func(T t){ writeln( 1 ); } } }For your example to work with template constraints, the most straightforward solution would be void func(T)(T t) if(!isIntegral!T) { writeln(1); } void func(T)(T t) if(isIntegral!T) { writeln(2); }Alternatively, you can use static if, though you're only dealing with one template in that case. e.g. void func(T)(T t) { static if(isIntegral!T) writeln(2); else writeln(1); } - Jonathan M Davis
Dec 21 2015
Thanks all for your replies. One question: Jonathan M Davis wrote:Alternatively, you can use static if, though you're only dealing with one template in that case. e.g.But if we wanted to deprecate one of the alternatives, then we necessary need to declare two templates with the same name and complementary constraints right? --
Dec 21 2015
On Monday, December 21, 2015 19:54:53 Shriramana Sharma via Digitalmars-d-learn wrote:Thanks all for your replies. One question: Jonathan M Davis wrote:Yes. Symbols get deprecated, not the internals of functions. So, you need a separate function declaration to be able to deprecate one of them - though tcak's example that separates the template from the function and uses a static if within the template to declare two separate functions would allow for the deprecation to be inside of the static if, since the static if is outside of the function. Personally, I'd just use template constraints though. - Jonathan M DavisAlternatively, you can use static if, though you're only dealing with one template in that case. e.g.But if we wanted to deprecate one of the alternatives, then we necessary need to declare two templates with the same name and complementary constraints right?
Dec 21 2015