I wrote an is_incrementable
trait like this:
#include <type_traits>
template <typename T, typename = void>
struct is_incrementable : std::false_type {};
template <typename T>
struct is_incrementable<T, std::void_t<decltype(++std::declval<T&>())>>
: std::true_type {};
template <typename T>
constexpr bool is_incrementable_v = is_incrementable<T>::value;
When I apply it to bool
with -std=c++17
on clang, it returns true
:
// This compiles
static_assert(is_incrementable_v<bool>, "");
But incrementing bool
is not allowed under c++17. Indeed, if I try to do it, I get an error:
bool b = false;
++b;
results in:
error: ISO C++17 does not allow incrementing expression of type bool [-Wincrement-bool]
Why does SFINAE report that bool
is incrementable, when the compiler clearly doesn't allow it?
Compiler explorer: https://godbolt.org/g/DDFYBf
It looks like Clang erroneously permits the incrementation of bool
values in not-evaluated contexts.
We can simplify your example using C++20 concepts:
template<class T>
concept is_incrementable = requires(T t) {
{ ++t };
};
int main() {
static_assert( is_incrementable<int> );
static_assert( !is_incrementable<bool> ); // Clang error here
}
This program is accepted in GCC and MSVC, but Clang shows the same wrong behaviour here, demo: https://gcc.godbolt.org/z/YEnKfG8T5
I think it is Clang bug, so submitted a bug report: https://bugs.llvm.org/show_bug.cgi?id=52280
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