Continuing my reading of ranges-v3 library, I realized that all of checks about valid expressions for template types has a tailing ", 42" expression, and I wonder what is the purpose of that. For example:
namespace concepts {
constexpr struct valid_expr
{
template<typename... T>
void operator()(T&&...) const;
};
}
struct ExplicitlyConvertibleTo
{
template<typename From, typename To>
auto requires_(From (&from)()) -> decltype(
concepts::valid_expr(
((void) static_cast<To>(from()), 42)
));
};
I understand some of the points of that implementation, like the inner parenthesis to force the use of the comma operator, the void-casting to avoid some overloads of the comma operator, etc, but why not just simply writting something like?
concepts::valid_expr(static_cast<To>(from()));
A small correction: In range-v3,
valid_expr
is an object not a type:Now, consider what happens if you use
concepts::valid_expr(static_cast<To>(from()))
as suggested andTo
isvoid
. It is allowable tostatic_cast
tovoid
, but it is not allowable to call a function with an argument which is avoid
expression.