digitalmars.D.learn - Default template arguments
- Joseph Rushton Wakeling (36/36) Nov 19 2012 Suppose I have a template, for which I provide a default parameter type....
- bearophile (5/9) Nov 19 2012 Take a look at how Complex does it:
- Joseph Rushton Wakeling (12/14) Nov 19 2012 Looking, but I don't think that's really what I'm looking for. AFAICS C...
- bearophile (20/21) Nov 19 2012 Second try:
- bearophile (21/21) Nov 19 2012 Better:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (5/25) Nov 19 2012 I like that! :)
- Tobias Pankrath (5/38) Nov 19 2012 Should check if it's implicit convertable. Most of the times you
- bearophile (5/8) Nov 19 2012 Right, my code wasn't complete, it's just a draft. It needs some
- Joseph Rushton Wakeling (16/25) Nov 19 2012 Thanks for the suggestion! :-)
Suppose I have a template, for which I provide a default parameter type. Is there any way of ensuring that this default will be respected unless the user explicitly requests an alternative type? As an example, consider the following: ////////////////////////////////////////// import std.stdio; void printSize(T = real)(T x) { writeln(x.sizeof); } void main() { float x; x.printSize(); x.printSize!float(); x.printSize!real(); } ////////////////////////////////////////// Here, a default type for T is given -- real -- but passing it a float overrides that default, which you can see because the printout of x.sizeof gives the size of a float instead of a real. In other words it outputs 4 4 16 Instead, what I'd like is a way to specify the template parameters so that the type would be _real unless otherwise specified_ -- in other words, so that the above would output 16 4 16 Reading through http://dlang.org/templates-revisited.html I can't see an evident way to do this. I've tried T:real in place of T = real, but the same behaviour results and in any case I don't think that syntax is intended for this kind of purpose. (Actually, the given description of T:int as indicating "T must be int type" would suggest that T:real would force T to be a real in all circumstances, but that's not what happens ...)
Nov 19 2012
Joseph Rushton Wakeling:Suppose I have a template, for which I provide a default parameter type. Is there any way of ensuring that this default will be respected unless the user explicitly requests an alternative type?Take a look at how Complex does it: https://github.com/D-Programming-Language/phobos/blob/master/std/complex.d Bye, bearophile
Nov 19 2012
On 11/19/2012 04:47 PM, bearophile wrote:Take a look at how Complex does it: https://github.com/D-Programming-Language/phobos/blob/master/std/complex.dLooking, but I don't think that's really what I'm looking for. AFAICS Complex basically operates along these rules: -- if your input value(s) are floating point then use the (common) type of those values; -- if not, then use double So if e.g. you replace those doubles in the complex() function with reals, then calling complex(1.0) will still get you back a Complex!double. By contrast I'm looking for something like: -- if the user doesn't _explicitly specify the type_ then use real, regardless of the type of the input. ... or have I missed something?
Nov 19 2012
Joseph Rushton Wakeling:... or have I missed something?Second try: import std.stdio; void printSize2(T)(T x) { writeln(T.stringof); } void printSize(T1 = void, T2 = real)(T2 x) { static if (is(T1 == void)) printSize2!real(x); else printSize2!T1(x); } void main() { float x; x.printSize(); // shoud be real x.printSize!float(); // shoud be float x.printSize!real(); // shoud be real } Bye, bearophile
Nov 19 2012
Better: import std.stdio; private void printSizeHelper(T)(T x) { writeln(T.stringof); } void printSize(T1 = void, T2)(T2 x) { static if (is(T1 == void)) printSizeHelper!real(x); else printSizeHelper!T1(x); } void main() { float x; x.printSize(); x.printSize!float(); x.printSize!real(); } (Keeping the two functions separated is useful against template bloat.) Bye, bearophile
Nov 19 2012
On 11/19/2012 09:44 AM, bearophile wrote:Better: import std.stdio; private void printSizeHelper(T)(T x) { writeln(T.stringof); } void printSize(T1 = void, T2)(T2 x) { static if (is(T1 == void)) printSizeHelper!real(x); else printSizeHelper!T1(x); } void main() { float x; x.printSize(); x.printSize!float(); x.printSize!real(); } (Keeping the two functions separated is useful against template bloat.) Bye, bearophileI like that! :) Is it possible or required to ensure that T1 is T2 in the static else clause? Ali
Nov 19 2012
On Monday, 19 November 2012 at 17:50:59 UTC, Ali Çehreli wrote:On 11/19/2012 09:44 AM, bearophile wrote:Should check if it's implicit convertable. Most of the times you use this pattern, you'll get an template error down in printSizeHelper, but you want your template hierarchy to fail as soon as possible.Better: import std.stdio; private void printSizeHelper(T)(T x) { writeln(T.stringof); } void printSize(T1 = void, T2)(T2 x) { static if (is(T1 == void)) printSizeHelper!real(x); else printSizeHelper!T1(x); } void main() { float x; x.printSize(); x.printSize!float(); x.printSize!real(); } (Keeping the two functions separated is useful against template bloat.) Bye, bearophileI like that! :) Is it possible or required to ensure that T1 is T2 in the static else clause? Ali
Nov 19 2012
Tobias Pankrath:Most of the times you use this pattern, you'll get an template error down in printSizeHelper, but you want your template hierarchy to fail as soon as possible.Right, my code wasn't complete, it's just a draft. It needs some template constraints. Bye, bearophile
Nov 19 2012
On 11/19/2012 06:44 PM, bearophile wrote:private void printSizeHelper(T)(T x) { writeln(T.stringof); } void printSize(T1 = void, T2)(T2 x) { static if (is(T1 == void)) printSizeHelper!real(x); else printSizeHelper!T1(x); }Thanks for the suggestion! :-) Now I think of it, is there anything wrong with, void printSizeHelper(T)(T x) { writeln(x.sizeof); } void printSize(T1 = real, T2)(T2 x) if(is(T2 : T1)) { printSizeHelper!T1(x); } ... bar some extra safety constraints, perhaps? I have a feeling I'd considered that solution at some point but had put it aside because I was feeling sure there must be a way that didn't involve creating an extra template parameter.
Nov 19 2012