Thread overview
Type-qualified functions?
Jan 21, 2011
Sean Eskapp
Jan 21, 2011
Sean Eskapp
Jan 21, 2011
Jesse Phillips
January 21, 2011
How does one avoid code duplication in a snippet code like this:

class A{}

void foo(const A, void delegate(const A) fn)
{
	// some stuff
	// ...
	// ...
}

void foo(A, void delegate(A) fn)
{
	// exact same stuff, with different qualifiers
	// ...
	// ...
}
January 21, 2011
On Fri, 21 Jan 2011 09:08:58 -0500, Sean Eskapp <eatingstaples@gmail.com> wrote:

> How does one avoid code duplication in a snippet code like this:
>
> class A{}
>
> void foo(const A, void delegate(const A) fn)
> {
> 	// some stuff
> 	// ...
> 	// ...
> }
>
> void foo(A, void delegate(A) fn)
> {
> 	// exact same stuff, with different qualifiers
> 	// ...
> 	// ...
> }

templates:

void foo(T)(T, void delegate(T) fn)
{
}

This parameterizes foo based on T, which could be A, const A, or int, or whatever works to compile the function.

You could further restrict which templates can be instantiated with a template constraint (say for instance, to restring foo to only instantiate when T is A or const(A) ).

-Steve
January 21, 2011
> templates:

> void foo(T)(T, void delegate(T) fn)
> {
> }

> This parameterizes foo based on T, which could be A, const A, or int, or whatever works to compile the function.

What if the parameters are more general, for instance the first parameter is always a Foo, the second is a delegate which takes a Foo.Bar, but they're always qualified the same way?
January 21, 2011
Sean Eskapp Wrote:

> 
> > templates:
> 
> > void foo(T)(T, void delegate(T) fn)
> > {
> > }
> 
> > This parameterizes foo based on T, which could be A, const A, or int, or whatever works to compile the function.
> 
> What if the parameters are more general, for instance the first parameter is always a Foo, the second is a delegate which takes a Foo.Bar, but they're always qualified the same way?

Their is probably better ways to do this...

void main() {
    foo(new Foo, (int) { });
}

void foo(T, U)(T t, void delegate(U) fn)
   if(__traits(compiles, fn(t.bar))) {
}

class Foo {
    int bar() {
        return 0;
    }
}
January 22, 2011
On 01/21/11 14:43, Sean Eskapp wrote:
> 
>> templates:
> 
>> void foo(T)(T, void delegate(T) fn)
>> {
>> }
> 
>> This parameterizes foo based on T, which could be A, const A, or int, or whatever works to compile the function.
> 
> What if the parameters are more general, for instance the first parameter is always a Foo, the second is a delegate which takes a Foo.Bar, but they're always qualified the same way?

I believe this is the sort of thing the 'inout' qualifier was meant for, except I don't know if it works with a void return type.  It's also worth noting that mutable and immutable are both castable to const, so if there is literally no difference between the two functions, see if you can get away with just the one using const.

-- Chris N-S