Date: Sat, 11 Jan 2025 21:58:57 +0100
I presume people here know about this, but for those not familiar:
int main() {
using hello = decltype([](){std::print("hello");});
using space = decltype([](){std::print(" ");});
using world = decltype([](){std::print("world");});
std::numeric_limits<hello>::min()();
std::numeric_limits<space>::lowest()();
std::numeric_limits<world>::max()();
}
prints out hello world <https://godbolt.org/z/4fTWWoE4E>, because for
"unrecognized" types default implementation just returns default
constructed value.
I presume this primary template specified in standard
https://eel.is/c++draft/numeric.limits
is specified as it is so that specializations can inherit members that they
do not want to modify, but
this still looks to me as less than an ideal solution.
While it is possible to use
static_assert(std::numeric_limits<T>::is_specialized) or verify assumptions
in generic code, in practice, such precautions seem uncommon. This can lead
to subtle bugs where generic code unintentionally relies on default values
for unsupported types, potentially causing incorrect behavior without an
immediate compile-time error.
I wonder if anybody ever considered fixing this in the standard(assuming
this problem actually exists and I did not misunderstood something).
I understand that backward compatibility may constrain changes to this
design, but it is library code so in theory std::limits or some other name
could be used for improved version without breaking any existing code.
int main() {
using hello = decltype([](){std::print("hello");});
using space = decltype([](){std::print(" ");});
using world = decltype([](){std::print("world");});
std::numeric_limits<hello>::min()();
std::numeric_limits<space>::lowest()();
std::numeric_limits<world>::max()();
}
prints out hello world <https://godbolt.org/z/4fTWWoE4E>, because for
"unrecognized" types default implementation just returns default
constructed value.
I presume this primary template specified in standard
https://eel.is/c++draft/numeric.limits
is specified as it is so that specializations can inherit members that they
do not want to modify, but
this still looks to me as less than an ideal solution.
While it is possible to use
static_assert(std::numeric_limits<T>::is_specialized) or verify assumptions
in generic code, in practice, such precautions seem uncommon. This can lead
to subtle bugs where generic code unintentionally relies on default values
for unsupported types, potentially causing incorrect behavior without an
immediate compile-time error.
I wonder if anybody ever considered fixing this in the standard(assuming
this problem actually exists and I did not misunderstood something).
I understand that backward compatibility may constrain changes to this
design, but it is library code so in theory std::limits or some other name
could be used for improved version without breaking any existing code.
Received on 2025-01-11 20:59:10