digitalmars.D.learn - Inferring function argument types from other argument types
- Joseph Rushton Wakeling <joseph.wakeling webdrake.net> Nov 12 2012
- "Vijay Nayar" <madric gmail.com> Nov 13 2012
- Joseph Rushton Wakeling <joseph.wakeling webdrake.net> Nov 13 2012
- "Vijay Nayar" <madric gmail.com> Nov 13 2012
Suppose that I've got a struct which internally defines a number of types:
struct Foo(_T1, _T2)
{
alias _T1 T1;
alias _T2 T2;
T1 a;
T2 b;
}
... and now I want to define a function which takes as input an instance of one
of these structs, and a variable of type T1.
I tried the following:
T func(FooT, T = FooT.T1)(FooT foo, T x)
{
return x * foo.a;
}
but found that the type of whatever I was passing would override the default:
e.g. if I called func(fooInstance, 1) then the second argument would be
interpreted as an int even though Foo.T1 is size_t.
I also tried,
T func(FooT, T : FooT.T1)(FooT foo, T x)
{
return x * foo.a;
}
but this generates a different error: "no property 'T1' for type 'FooT'". I
tried replacing FooT with alias FooT to no avail.
Obviously I could get round the problems of the first example with something
based around CommonType etc. but I'm just wondering if it's possible to make an
argument dependent on another template parameter in the way I'm looking for
here.
Nov 12 2012
I believe this question was asked before, but here is the
solution again.
struct Foo(_T1, _T2)
{
alias _T1 T1;
alias _T2 T2;
T1 a;
T2 b;
}
FooT.T1 func(FooT, T)(FooT foo, T x)
if (is(FooT.T1) && is(T : FooT.T1))
{
return x * foo.a;
}
void main() {
auto foo = Foo!(size_t, string)(8, "bobcat");
int value = 3;
assert(foo.func(value) == 24);
assert(is(typeof(foo.func(value)) == size_t));
}
- Vijay
On Monday, 12 November 2012 at 12:42:31 UTC, Joseph Rushton
Wakeling wrote:
Suppose that I've got a struct which internally defines a
number of types:
struct Foo(_T1, _T2)
{
alias _T1 T1;
alias _T2 T2;
T1 a;
T2 b;
}
... and now I want to define a function which takes as input an
instance of one of these structs, and a variable of type T1.
I tried the following:
T func(FooT, T = FooT.T1)(FooT foo, T x)
{
return x * foo.a;
}
but found that the type of whatever I was passing would
override the default: e.g. if I called func(fooInstance, 1)
then the second argument would be interpreted as an int even
though Foo.T1 is size_t.
I also tried,
T func(FooT, T : FooT.T1)(FooT foo, T x)
{
return x * foo.a;
}
but this generates a different error: "no property 'T1' for
type 'FooT'". I tried replacing FooT with alias FooT to no
avail.
Obviously I could get round the problems of the first example
with something based around CommonType etc. but I'm just
wondering if it's possible to make an argument dependent on
another template parameter in the way I'm looking for here.
Nov 13 2012
On 11/13/2012 05:05 PM, Vijay Nayar wrote:I believe this question was asked before, but here is the solution again.
The actual reality of what I'm trying to do is slightly more complex: it's more like struct Foo(_T1, _T2) { alias _T1 T1; alias _T2 T2; // etc. } FooT.T1 func(FooT, T)(FooT foo, T x) { return func2(x); } ... where func2() is also a templated function, and it's important that it take a type of FooT.T1 and not T. So, I can't see what the solution is apart from casting x to FooT.T or explicitly indicating FooT.T1 as a template parameter for func2.
Nov 13 2012
Ok, I get it.
My understanding is that you have basically two options.
* If you want the function to be called with any implicitly
castable type, then you must cast it in the function.
* If you only want the function to accept the one type,
then use is(T == FooT.T1) and you must cast the input
the function.
However, all this feels like an over complication and round-about
way of
doing things. If you have exact types that must be specified in
the
struct, you probably don't want an external template at all.
Simply place
the function in the struct.
struct Foot(_T1, _T2) {
...
_T1 func(_T1 x) {
return func2(x);
}
}
- Vijay
On Tuesday, 13 November 2012 at 16:39:55 UTC, Joseph Rushton
Wakeling wrote:
On 11/13/2012 05:05 PM, Vijay Nayar wrote:
I believe this question was asked before, but here is the
solution again.
The actual reality of what I'm trying to do is slightly more
complex: it's more like
struct Foo(_T1, _T2)
{
alias _T1 T1;
alias _T2 T2;
// etc.
}
FooT.T1 func(FooT, T)(FooT foo, T x)
{
return func2(x);
}
... where func2() is also a templated function, and it's
important that it take a type of FooT.T1 and not T.
So, I can't see what the solution is apart from casting x to
FooT.T or explicitly indicating FooT.T1 as a template parameter
for func2.
Nov 13 2012









"Vijay Nayar" <madric gmail.com> 