diff --git a/stl/inc/type_traits b/stl/inc/type_traits index 3071d591977..d1a88f9c28b 100644 --- a/stl/inc/type_traits +++ b/stl/inc/type_traits @@ -1764,7 +1764,7 @@ constexpr auto invoke(_Callable&& _Obj, _Ty1&& _Arg1, _Types2&&... _Args2) noexc #pragma warning(disable : 4365) // '%s': conversion from '%s' to '%s', signed/unsigned mismatch (/Wall) template , bool = is_void_v<_To>> -_INLINE_VAR constexpr bool _Is_nothrow_convertible_v = noexcept(_Fake_copy_init<_To>(_STD declval<_From>())); +_INLINE_VAR constexpr bool _Is_nothrow_convertible_v = noexcept(_STD _Fake_copy_init<_To>(_STD declval<_From>())); #pragma warning(pop) @@ -1784,7 +1784,7 @@ _EXPORT_STD template inline constexpr bool is_nothrow_convertible_v = _Is_nothrow_convertible_v<_From, _To>; _EXPORT_STD template -using is_nothrow_convertible = _Is_nothrow_convertible<_From, _To>; +struct is_nothrow_convertible : bool_constant<_Is_nothrow_convertible_v<_From, _To>> {}; #endif // _HAS_CXX20 template diff --git a/tests/std/tests/P0758R1_is_nothrow_convertible/test.compile.pass.cpp b/tests/std/tests/P0758R1_is_nothrow_convertible/test.compile.pass.cpp index 041abc2d4a4..06dfe28844d 100644 --- a/tests/std/tests/P0758R1_is_nothrow_convertible/test.compile.pass.cpp +++ b/tests/std/tests/P0758R1_is_nothrow_convertible/test.compile.pass.cpp @@ -105,5 +105,32 @@ STATIC_ASSERT(is_nothrow_convertible_v); STATIC_ASSERT(!is_nothrow_convertible_v); STATIC_ASSERT(!is_nothrow_convertible_v); +// Also test GH-4317 : some traits are aliases and fail when used with parameter packs + +template +using aliased_is_nothrow_convertible = is_nothrow_convertible; + +template class Tmpl> +constexpr bool is_specialization_of_v = false; +template class Tmpl> +constexpr bool is_specialization_of_v, Tmpl> = true; + +STATIC_ASSERT(is_specialization_of_v, is_nothrow_convertible>); +STATIC_ASSERT(!is_specialization_of_v, aliased_is_nothrow_convertible>); + +#ifndef _M_CEE // TRANSITION, VSO-1659496 +// Also test that is_nothrow_convertible/is_nothrow_convertible_v are ADL-proof + +template +struct holder { + T t; +}; + +struct incomplete; + +STATIC_ASSERT(is_nothrow_convertible*, holder*>::value); +STATIC_ASSERT(is_nothrow_convertible_v*, holder*>); +#endif // _M_CEE + // VSO_0105317_expression_sfinae and VSO_0000000_type_traits provide // additional coverage of this machinery