[Bug c++/87464] Gcc reports hard error instead of SFINAE out the related method
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sun Jan 2 11:25:16 GMT 2022
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87464
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Severity|normal |enhancement
Last reconfirmed| |2022-01-02
Status|UNCONFIRMED |NEW
Ever confirmed|0 |1
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Reduced:
template<bool, typename T> struct enable_if { };
template<typename T> struct enable_if<true, T> { using type = T; };
template<typename T> struct is_const { static constexpr bool value = false; };
template<typename T> struct is_const<const T> { static constexpr bool value =
true; };
template<typename T>
struct SfinaeTest
{
SfinaeTest() = default;
SfinaeTest(const SfinaeTest&) = default;
template<typename TT, typename enable_if< !is_const<TT>::value, int>::type =
0>
SfinaeTest(const SfinaeTest<TT>& other)
{ }
};
int main ()
{
SfinaeTest<int> p;
SfinaeTest<const int> c;
SfinaeTest<int> b_c( c); // expected error. Extra gcc-error: see L:13
}
GCC prints two errors, one is the substitution failure error.
Clang only prints one, for the invalid constructor call for b_c. Clang has a
special case for enable_if constraints, where it prints the boolean condition:
<source>:14:4: note: candidate template ignored: requirement '!is_const<const
int>::value' was not satisfied [with TT = const int]
If we rename the enable_if template, Clang still doesn't show an error, but is
closer to GCC's wording:
template<bool, typename T> struct require { };
template<typename T> struct require<true, T> { using type = T; };
template<typename T> struct is_const { static constexpr bool value = false; };
template<typename T> struct is_const<const T> { static constexpr bool value =
true; };
template<typename T>
struct SfinaeTest
{
SfinaeTest() = default;
SfinaeTest(const SfinaeTest&) = default;
template<typename TT, typename require< !is_const<TT>::value, int>::type =
0>
SfinaeTest(const SfinaeTest<TT>& other)
{ }
};
int main ()
{
SfinaeTest<int> p;
SfinaeTest<const int> c;
SfinaeTest<int> b_c( c); // expected error. Extra gcc-error: see L:15
}
Now clang's note for the template constructor says:
<source>:14:4: note: candidate template ignored: substitution failure [with TT
= const int]: no type named 'type' in 'require<false, int>'
So the only real difference is that gcc prints the cause of the substitution
failure as an error.
More information about the Gcc-bugs
mailing list