C++ guys hate static_if?
monarch_dodra
monarchdodra at gmail.com
Sun Mar 10 09:05:36 PDT 2013
On Sunday, 10 March 2013 at 02:35:28 UTC, Walter Bright wrote:
> On 3/9/2013 8:22 AM, monarch_dodra wrote:
>> Things can get evenmore hairy,when you are operating on 2
>> different types.
>
> This is why complex expressions can be encapsulated as
> functions.
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.
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.
That said, we can also look for a "middle ground" where the
constraints validate the broad requirements (RA, comparable), and
the asserts validate the more complex stuff.
>> 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.
NOW, if we had defined a.do_it with concepts/static asserts, the
programmer would have been served with a "ambiguous call: a.do_it
or b.do_it"? So the coder would have to be "alright, I want to
explicitly call a.do_it". To which this time the compiler replies
"Error: isForwardRange!MyInputRange is false". To which the
programmer replies "I understand my error and see what I did
wrong".
--------------------------------------
I'm not saying template constraints are bad or anything, I think
they are incredible tools for dispatching to specialized
overloads.
However, In regards to *validating* the input, I think
concepts/static asserts, are both more robust
implementation-wise, while being clearer for the end coder.
More information about the Digitalmars-d
mailing list