-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Description
Hi,
Is it intended for gsl::narrow_cast<T>(u) and gsl::narrow<T>(u) to only be usable with arithmetic types (so both T and the type of u must be arithmetic)?
In the current GSL implementation, gsl::narrow<T>(u) is being guarded by std::enable_if std::is_arithmetic<T>, but gsl::narrow_cast<T>(u) has no such guards. In fact, gsl::narrow_cast is essentially a wrapper around static_cast.
The guard on gsl::narrow<T>(u) prevents T from being non-arithmetic. Furthermore, the implementation of gsl::narrow will cause the code to fail to compile if static_cast<U>(narrow_cast<T>(u)) != u (where U is the type of u) is not valid. Together with the guard on T, this should prevent non-arithmetic types from being used for either of T or U. However, cases like the following actually slip through. This case does not result in a narrowing implicit/explicit conversion.
struct A
{
A() {}
A(int) {}
operator int() { return 42; }
};
int main() {
A a{42};
gsl::narrow_cast<int>(a); // compiles and executes with no failures/errors
}
Thanks,
Dmitry