Given this C++11 code:
#include <type_traits>
enum Enum { EnumValue };
template <typename>
struct Pred { constexpr static bool const value = true; };
template <
typename T,
typename ::std::enable_if<
Pred<T>::value,
Enum
>::type = EnumValue>
class Huh {};
template <typename T>
constexpr bool f(Huh<T> const &) noexcept { return true; }
static_assert(f(Huh<int>()), "");
I get the following error message from GCC 7.3.0:
test.cpp:19:27: error: no matching function for call to 'f(Huh<int>)'
static_assert(f(Huh<int>()), "");
^
test.cpp:17:16: note: candidate: template<class T> constexpr bool f(const Huh<T>&)
constexpr bool f(Huh<T> const &) noexcept { return true; }
^
test.cpp:17:16: note: template argument deduction/substitution failed:
test.cpp:19:27: note: template argument '(type)0' does not match 'EnumValue'
static_assert(f(Huh<int>()), "");
^
If I use int
and 0
instead of Enum
and EnumValue
, the error is gone. Why does this fail with an enum?
Does anyone have any idea about how to work around this on broken versions of GCC while keeping the enum?
You can grit your teeth and tell the compiler what it fails to deduce:
static_assert(f<int>(Huh<int>()), "");
Success
If the unsightliness would be widespread maybe you can localize it in some conditionally compiled wrapping.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With