On Thursday, 31 July 2014 at 20:34:42 UTC, Vlad Levenfeld wrote:
What's the rationale behind stating the condition this way as
opposed to, say,
is (typeof(R.init.save)) == R) || is ((typeof(R.init.save()) ==
R)
so that member fields as well as @property and non-@property
methods will match
save should never have been a property, since it doesn't really
emulate a variable, but because it was decided that it was a
property, it is required by the API that it be a property. And
the reason why it's required to be a property once it was decided
that it should be one is quite simple. What would happen if you a
function did this
auto s = range.save();
and save was a property? The code would fail to compile. Because
it was decided that save should be a property, _every_ time that
save is used, it must be used as a property, or it won't work
with any range that did define save as a property. As such, there
is no reason to allow save to be a non-property function.
Allowing that would just make it easier to write code which
called save incorrectly but worked with the ranges that it was
tested with (because they defined save as a function instead of a
property). In addition, if it works with your range, it's
perfectly legal to define save as a member variable (though that
would be a rather bizarre thing to do), and allowing save to be
called as a function by the range API would break that.
So, once it's been decided that it's legal for something in a
templated API to be a property, it _must_ be a property, a
variable, or an enum, or there are going to be problems, because
it has to be used without parens.
- Jonathan M Davis