[Bug c++/106143] Add fix-it for missing ::value on trait with std::integral_constant base
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Jun 30 09:07:56 GMT 2022
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106143
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Clang gives a different error, but no more helpful:
v.C:2:34: error: expected '(' for function-style cast or type construction
static_assert( std::is_void<void>, "void is void is void" );
~~~~~~~~~~~~~~~~~~^
v.C:3:38: error: expected '(' for function-style cast or type construction
constexpr bool b = std::is_void<void>;
~~~~~~~~~~~~~~~~~~^
2 errors generated.
This is pointing out that std::is_void<void>() would fix it, which is true. And
it's maybe more helpful than just saying "expected primary-expression" (which
means nothing to most users). But for the specific case of type traits we can
do better: using ::value to access the static member is more efficient to
compile than constructing a temporary and then finding its implicit conversion
to bool. So we should suggest ::value and not suggest ()
Maybe for C++17 we could also recognise when the derived trait type is in
namespace std and suggest the std::is_void_v variable template instead, on the
assumption that every std:: trait has a corresponding variable template now.
Ville suggests that instead of checking for a std::integral_constant base we
could just check if there's a nested ::value that is convertible to bool. That
would make it also work for boost-style traits that use an enumerator instead
of a static member, e.g.
struct is_foo { enum value = true; }; };
So maybe if we're using C++17, and it's a type defined in namespace std that
has a base class of std::integral_constant<bool, B>, then suggest is_foo_v<T>.
Otherwise, if is_foo<T>::value exists and is convertible to bool, then suggest
is_foo<T>::value.
Otherwise, either print the current diagnostic, or maybe something more
user-friendly that says "you used a type where a value is needed", like EDG
does:
"v.C", line 2: error: type name is not allowed
static_assert( std::is_void<void>, "void is void is void" );
^
"v.C", line 3: error: type name is not allowed
constexpr bool b = std::is_void<void>;
^
More information about the Gcc-bugs
mailing list