Thread overview | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 06, 2013 Fun with templates | ||||
---|---|---|---|---|
| ||||
Attachments:
| Okay, so I feel like this should be possible, but I can't make it work... I want to use template deduction to deduce the argument type, but I want the function arg to be Unqual!T of the deduced type, rather than the verbatim type of the argument given. I've tried: void f(T : Unqual!U, U)(T a) {} and: void f(T)(Unqual!T a) {} Ie, if called with: const int x; f(x); Then f() should be generated void f(int) rather than void f(const int). I don't want a million permutations of the template function for each combination of const/immutabe/shared/etc, which especially blows out when the function has 2 or more args. Note: T may only be a primitive type. Obviously const(int*) can never be passed to int*. |
July 06, 2013 Re: Fun with templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | "Manu" <turkeyman@gmail.com> wrote in message news:mailman.1752.1373074509.13711.digitalmars-d@puremagic.com... > Okay, so I feel like this should be possible, but I can't make it work... I want to use template deduction to deduce the argument type, but I want the function arg to be Unqual!T of the deduced type, rather than the verbatim type of the argument given. > > I've tried: void f(T : Unqual!U, U)(T a) {} > and: void f(T)(Unqual!T a) {} > > Ie, if called with: > const int x; > f(x); > Then f() should be generated void f(int) rather than void f(const int). > > I don't want a million permutations of the template function for each combination of const/immutabe/shared/etc, which especially blows out when the function has 2 or more args. > > Note: T may only be a primitive type. Obviously const(int*) can never be > passed to int*. > void f(T)(T _a) { Unqual!T a = _a; ... } |
July 06, 2013 Re: Fun with templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Saturday, 6 July 2013 at 01:35:09 UTC, Manu wrote:
> Okay, so I feel like this should be possible, but I can't make it work...
> I want to use template deduction to deduce the argument type, but I want
> the function arg to be Unqual!T of the deduced type, rather than the
> verbatim type of the argument given.
>
> I've tried: void f(T : Unqual!U, U)(T a) {}
> and: void f(T)(Unqual!T a) {}
>
> Ie, if called with:
> const int x;
> f(x);
> Then f() should be generated void f(int) rather than void f(const int).
>
> I don't want a million permutations of the template function for each
> combination of const/immutabe/shared/etc, which especially blows out when
> the function has 2 or more args.
>
> Note: T may only be a primitive type. Obviously const(int*) can never be
> passed to int*.
this?
template f(T)
{
void f (T x)
{
f_i(x);
}
void f_i(Unqual!T x)
{
writefln("%s", x);
}
}
|
July 06, 2013 Re: Fun with templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Saturday, 6 July 2013 at 01:35:09 UTC, Manu wrote:
> Okay, so I feel like this should be possible, but I can't make it work...
I don't think D's IFTI allows different argument and parameter types...
I think this is possible with a proxy function (a function that accepts arguments with any qualifiers, but forwards them to the real function after stripping away top-level qualifiers). Should be possible to create something that auto-generates such a proxy function. A small proxy function will likely be inlined, and would avoid template bloat.
Another possible way:
Unqual!T unqual(T)(T v) { return v; }
Then use unqual(x) whenever calling the function (although you'd have to remember to, which sucks).
|
July 06, 2013 Re: Fun with templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On 07/06/2013 03:34 AM, Manu wrote:
> Okay, so I feel like this should be possible, but I can't make it work...
> I want to use template deduction to deduce the argument type, but I want
> the function arg to be Unqual!T of the deduced type, rather than the
> verbatim type of the argument given.
>
> I've tried: void f(T : Unqual!U, U)(T a) {}
> and: void f(T)(Unqual!T a) {}
>
> Ie, if called with:
> const int x;
> f(x);
> Then f() should be generated void f(int) rather than void f(const int).
>
> I don't want a million permutations of the template function for each
> combination of const/immutabe/shared/etc, which especially blows out
> when the function has 2 or more args.
>
> Note: T may only be a primitive type. Obviously const(int*) can never be
> passed to int*.
void f(T)(const(T) a) {}
This will strip off const, immutable and inout, but not shared.
I'd have thought that
void f(T)(const(shared(T)) a) {}
would strip shared as well, but DMD does not match int to const(shared(int)) at all which I think is incorrect.
|
July 06, 2013 Re: Fun with templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Murphy Attachments:
| On 6 July 2013 11:41, Daniel Murphy <yebblies@nospamgmail.com> wrote:
>
> "Manu" <turkeyman@gmail.com> wrote in message news:mailman.1752.1373074509.13711.digitalmars-d@puremagic.com...
> > Okay, so I feel like this should be possible, but I can't make it work... I want to use template deduction to deduce the argument type, but I want the function arg to be Unqual!T of the deduced type, rather than the verbatim type of the argument given.
> >
> > I've tried: void f(T : Unqual!U, U)(T a) {}
> > and: void f(T)(Unqual!T a) {}
> >
> > Ie, if called with:
> > const int x;
> > f(x);
> > Then f() should be generated void f(int) rather than void f(const int).
> >
> > I don't want a million permutations of the template function for each combination of const/immutabe/shared/etc, which especially blows out when the function has 2 or more args.
> >
> > Note: T may only be a primitive type. Obviously const(int*) can never be
> > passed to int*.
> >
>
> void f(T)(T _a) { Unqual!T a = _a; ... }
>
That doesn't do what I want at all. The signature is still f(T) not
f(Unqual!T).
|
July 06, 2013 Re: Fun with templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to finalpatch Attachments:
| On 6 July 2013 11:42, finalpatch <fengli@gmail.com> wrote:
> On Saturday, 6 July 2013 at 01:35:09 UTC, Manu wrote:
>
>> Okay, so I feel like this should be possible, but I can't make it work... I want to use template deduction to deduce the argument type, but I want the function arg to be Unqual!T of the deduced type, rather than the verbatim type of the argument given.
>>
>> I've tried: void f(T : Unqual!U, U)(T a) {}
>> and: void f(T)(Unqual!T a) {}
>>
>> Ie, if called with:
>> const int x;
>> f(x);
>> Then f() should be generated void f(int) rather than void f(const int).
>>
>> I don't want a million permutations of the template function for each combination of const/immutabe/shared/etc, which especially blows out when the function has 2 or more args.
>>
>> Note: T may only be a primitive type. Obviously const(int*) can never be
>> passed to int*.
>>
>
> this?
>
> template f(T)
> {
> void f (T x)
> {
> f_i(x);
> }
> void f_i(Unqual!T x)
> {
> writefln("%s", x);
> }
> }
>
And again, f(T), the signature is wrong. There is also an additional call... twice as slow when non-optimised :/
|
July 06, 2013 Re: Fun with templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr Attachments:
| On 6 July 2013 11:45, Timon Gehr <timon.gehr@gmx.ch> wrote:
> On 07/06/2013 03:34 AM, Manu wrote:
>
>> Okay, so I feel like this should be possible, but I can't make it work... I want to use template deduction to deduce the argument type, but I want the function arg to be Unqual!T of the deduced type, rather than the verbatim type of the argument given.
>>
>> I've tried: void f(T : Unqual!U, U)(T a) {}
>> and: void f(T)(Unqual!T a) {}
>>
>> Ie, if called with:
>> const int x;
>> f(x);
>> Then f() should be generated void f(int) rather than void f(const int).
>>
>> I don't want a million permutations of the template function for each combination of const/immutabe/shared/etc, which especially blows out when the function has 2 or more args.
>>
>> Note: T may only be a primitive type. Obviously const(int*) can never be
>> passed to int*.
>>
>
> void f(T)(const(T) a) {}
>
> This will strip off const, immutable and inout, but not shared.
>
> I'd have thought that
>
> void f(T)(const(shared(T)) a) {}
>
> would strip shared as well, but DMD does not match int to
> const(shared(int)) at all which I think is incorrect.
>
So what is the signature of f() in this case? It looks like the function
receives const(T), not T.
It looks like it sets T to Unqual!T, but it's not T that I'm interested in,
it's the function argument being deduced to the correct type.
We can do impressive stuff like this:
void f(T : U[N], U, size_t N)(T x); .. but I suppose in that example, T
is still the supplied type verbatim, it's just performing a lot of fancy
work to decompose it.
So then I wonder if my question becomes, with parameter type deduction, is
it an absolute requirement that the parameter type is taken to be the
supplied argument's type verbatim (and not possibly something it is
implicitly castable to)?
Is there ANY way to flex this rule while retaining the functionality of
argument type deduction?
|
July 06, 2013 Re: Fun with templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | "Manu" <turkeyman@gmail.com> wrote in message news:mailman.1754.1373081562.13711.digitalmars-d@puremagic.com... > On 6 July 2013 11:41, Daniel Murphy <yebblies@nospamgmail.com> wrote: > >> >> "Manu" <turkeyman@gmail.com> wrote in message news:mailman.1752.1373074509.13711.digitalmars-d@puremagic.com... >> > Okay, so I feel like this should be possible, but I can't make it >> > work... >> > I want to use template deduction to deduce the argument type, but I >> > want >> > the function arg to be Unqual!T of the deduced type, rather than the >> > verbatim type of the argument given. >> > >> > I've tried: void f(T : Unqual!U, U)(T a) {} >> > and: void f(T)(Unqual!T a) {} >> > >> > Ie, if called with: >> > const int x; >> > f(x); >> > Then f() should be generated void f(int) rather than void f(const int). >> > >> > I don't want a million permutations of the template function for each >> > combination of const/immutabe/shared/etc, which especially blows out >> > when >> > the function has 2 or more args. >> > >> > Note: T may only be a primitive type. Obviously const(int*) can never >> > be >> > passed to int*. >> > >> >> void f(T)(T _a) { Unqual!T a = _a; ... } >> > > That doesn't do what I want at all. The signature is still f(T) not > f(Unqual!T). > Yeah it's possible I didn't finish reading your post. |
Copyright © 1999-2021 by the D Language Foundation