Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to specialize variadic eponymous templates?

Tags:

d

I want to extend min so that it also works with my vector types.

For example min for two vectors should return a new vector that is composed of the lowest values of the two vectors.

min(Vec2(5,10), Vec2(-1, 15)) == Vec2(-1, 10)
auto min(Vec...)(in Vec v){
    static import std.algorithm.comparison;
    return componentMap!(std.algorithm.comparison.min)(v);
}
auto max(Vec...)(in Vec v){
    static import std.algorithm.comparison;
    return componentMap!(std.algorithm.comparison.max)(v);
}

It seems that I can not extend min. If the two min's are in the same scope then D will just choose std.algorithm.comparison.min and it will fail to compile. Is it possible to specialize the min template so that if D finds a min template that only contains vectors it will call the correct min template?

like image 411
Maik Klein Avatar asked Dec 01 '25 09:12

Maik Klein


1 Answers

std.algorithm.min doesn't have any template contraints (at least not any that are useful here), so it will be difficult to override if it is visible in the current scope. However, if you haven't imported min, you can write a wrapper like so:

enum isVector(T) = is(T == Vec2);

auto min(T...)(T args) {
    static import std.algorithm.comparison;

    static if (allSatisfy!(isVector, T))
            // return vector min
    else
        return std.algorithm.comparison.min(args);
}

The weird part is that the above actually works for me if I import std.algorithm.comparison; but not if I import std.algorithm.comparison : min;, which may be a bug.

However, I think your min departs far enough from normal min behavior (rather than returning one of the elements, it returns some combination thereof) that it may make sense to just give it a different name.

like image 101
rcorre Avatar answered Dec 04 '25 08:12

rcorre



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!