While playing around with the detection idiom and void_t
I found that expressions where the subtraction operator and void* are involved lead to different errors in the tested compilers.
GCC 10.2 and below, no matter if C++11,14,17 or 20 is used, seem to treat some expressions as hard error rather then substitution failures.
I'm working with the following (striped down) example
#include <type_traits>
template< class, class, class = void >
struct has_minus_void_t : std::false_type {};
template<class T, class U>
struct has_minus_void_t<T, U, std::void_t<
decltype(T() - U())
>> : std::true_type {};
static_assert(has_minus_void_t<int*,int*>::value, "int*");
static_assert(!has_minus_void_t<int*,void*>::value, "intvoid*");
static_assert(!has_minus_void_t<void*,int*>::value, "voidint*");
static_assert(!has_minus_void_t<void*,void*>::value, "void*");
and would expect the code to compile without errors for all four language standards (contains a std::void_t
replacement for pre C++17 so more standards can be tested) but
- GCC 10.2 and below complain about the last two asserts
- Clang doesn't complain
- MSVC complains about the int*/void* combination
I tried to search for an existing bug report but couldn't find one.
I'm wondering which compiler is right and why.