strong_type
strong_type copied to clipboard
Overriding std::is_arithmetic<> for program-defined type is undefined behaviour?
In the README, it's specified:
For modifier strong::arithmetic, the type trait std::is_arithmetic<> is true.
According to the standard, this is undefined behaviour:
- None of the templates defined in <type_traits> may be specialized for a program-defined type, except for std::common_type and std::basic_common_reference (since C++20). This includes the type traits and the class template std::integral_constant.
Maybe std::numeric_limits<>
should be specialised instead, to provide type-traits? That one is open to extension, provided one doesn't reopen the std
namespace and just specialises the fully-qualified name of the template...
Right. Bummer. I should've known this. Dropping it is also a potentially breaking change for some users, but it's the way to go. Thanks for reporting.
related to specializing std::is_arithmetic
, this code gives me a compile error with catch2 v3
TEST_CASE( "testme", "" )
{
using test_type
= strong::type< std::int8_t, struct tag, strong::arithmetic, strong::default_constructible, strong::equality >;
constexpr test_type a;
test_type b;
CHECK( a == b );
}
my/test.cpp: error: use of overloaded operator '<=' is ambiguous (with operand types 'Catch::Decomposer' and 'const test_type' (aka 'const type<signed char, tag, strong::arithmetic, strong::default_constructible, strong::equality>'))
catchAssertionHandler.handleExpr( Catch::Decomposer() <= a == b );
~~~~~~~~~~~~~~~~~~~ ^ ~
/path/to/catch2-v3/src/catch2/../catch2/internal/catch_decomposer.hpp:247:21: note: candidate function [with T = const strong::type<signed char, tag, strong::arithmetic, strong::default_constructible, strong::equality> &, $1 = 0]
friend auto operator <= ( Decomposer &&, T && lhs ) -> ExprLhs<T const&> {
^
/path/to/catch2-v3/src/catch2/../catch2/internal/catch_decomposer.hpp:252:21: note: candidate function [with T = strong::type<signed char, tag, strong::arithmetic, strong::default_constructible, strong::equality>, $1 = 0]
friend auto operator <= ( Decomposer &&, T value ) -> ExprLhs<T> {
^
1 error generated.
Thanks @timblechmann , that was a very unexpected result of this. I'll get to fixing it as soon as I'm out of meetings.
Fixed on main now. Leaving this open until a release is tagged.
Hurrah! How do you feel about going down the route of specializing std::numeric_limits<>
instead?
IIRC, there are members within that struct that can provide similar traits-like functionality as you were providing with is_arithmetic
, though I forget the names of the exact members.
I've got a previous specialisation of that struct I did for a personal project, maybe I'll dig that out (there's loads of definitions ☹️) and have a go hacking on strong_type...
@saxbophone feel free to open a separate issue about that.
Fix included in release v5
@saxbophone feel free to open a separate issue about that.
Thanks, I think I will and I will also try and send a PR with the structure of the type traits stuff I mentioned.