C++ guys hate static_if?

Walter Bright newshound2 at digitalmars.com
Sun Mar 10 12:14:19 PDT 2013


On 3/10/2013 9:05 AM, monarch_dodra wrote:
> Yes, but that doesn't solve the "root" issue of meaningfulness. Sure, instead of
> having a 5 line constraint, it's only a single line, but are these any better?
>
> sort(R, Scheme)(...)
> if(isRandomAccessRangeWithComparableElementsAndAssignableElementsIfStableSchemeOrSwapableElementsOtherwise!R)
>
>
> or
>
> sort(...)
>      if(meetsSortConstraints!R)
>
> Neither are really any better for the end user.

I don't think this issue is any different from selecting a name for any function 
that does something non-trivial. It's why we have functions - to encapsulate 
complexity.


> This is why I don't think constraints should be used at all for validating
> arguments. [concepts|static asserts] are much better, and when combined with
> static if, become incredibly powerful:
>
> sort(R, Scheme)(...)
> {
>      static assert (isRandomAccessRange!T);
>      static assert (is(typeof(r.front < r.front)));
>      static if (Scheme == Stable)
>          static assert (hasAssignableElements!T);
>      else
>          static assert (hasSwapableElements!T);
>
>      //Code Code Code
> }
>
> Much clearer, and the diagnostics much better.

Whether it's clearer or not is all in how you choose to organize/write them. 
Also, the static assert model does not enter into overload selection, while 
constraints do.



>>> One last thing to keep in mind is that having constraints allows hijacking,
>>> whereas concpets/static asserts resolve as an ambigus call.
>>
>> I don't see where the hijacking comes in.
>
> The problem with contraints is that it merelly eliminates functions from the
> pool of overloads. If you attemp to call a function with invalid parameters,
> then you may end up accidentally calling something you didn't want to. Imagine:
>
> //----
> module a;
> void do_it(R)(R r)
>      if (isForwardRange!R)
> {
>      //Do something to r
> }
> //----
> module b;
> void do_it(T)(T t)
> {
>      //Do something completely different
> }
> //----
> import a, b;
>
> void main()
> {
>      MyInputRange myInputRange; //Oops! I didn't realize it's only input:
>      do_it(myInputRange); //meant to call a.do_it;
> }
> //----
>
> With the current scheme of constraints, this will end up calling b.do_it,
> without any ambiguity. You may or may not consider that is "hijacking", but it
> is error prone.

That is not hijacking. Hijacking is when a template or function **from an 
unrelated scope** matches better and steals the call away. When 
templates/functions are in the same scope, it is just a usual overloading issue. 
It's not an undue burden on the programmer to pay attention to the overloads in 
the same scope. He's got to do that anyway.



More information about the Digitalmars-d mailing list