Issue |
135190
|
Summary |
Clang considers fold expanded constraint ambiguous when it shouldn't be
|
Labels |
clang
|
Assignees |
|
Reporter |
brevzin
|
Example (from [StackOverflow](https://stackoverflow.com/q/79565469/2069064)):
```cpp
template <class T> inline constexpr bool is_integral_v = false;
template <> inline constexpr bool is_integral_v<int> = true;
template <class T> inline constexpr bool is_floating_point_v = false;
template <> inline constexpr bool is_floating_point_v<double> = true;
template <class T> inline constexpr bool is_arithmetic_v = false;
template <> inline constexpr bool is_arithmetic_v<int> = true;
template <> inline constexpr bool is_arithmetic_v<double> = true;
#if WHICH
template <class T> concept floating_point = is_floating_point_v<T>;
template <class T> concept integral = is_integral_v<T>;
template <class T> concept arithmetic = floating_point<T> or integral<T>;
#else
template <class T> concept arithmetic = is_arithmetic_v<T>;
template <class T> concept floating_point = arithmetic<T> and is_floating_point_v<T>;
#endif
// ------------------------------------
template <arithmetic... Ts>
constexpr int f() {
return 1;
}
template <floating_point... Ts>
constexpr int f() {
return 2;
}
static_assert(f<int>() == 1); // ok
static_assert(f<double>() == 2); // ok
// ------------------------------------
template <class... Ts>
requires(arithmetic<Ts> && ...)
constexpr int g() {
return 1;
}
template <class... Ts>
requires(floating_point<Ts> && ...)
constexpr int g() {
return 2;
}
static_assert(g<int>() == 1); // ok
static_assert(g<double>() == 2); // ok
// ------------------------------------
template <class... Ts>
concept all_arithmetic = (arithmetic<Ts> && ...);
template <class... Ts>
concept all_floating_point = (floating_point<Ts> && ...);
template <class... Ts>
requires all_arithmetic<Ts...>
constexpr int h() {
return 1;
}
template <class... Ts>
requires all_floating_point<Ts...>
constexpr int h() {
return 2;
}
static_assert(h<int>() == 1); // ok
static_assert(h<double>() == 2); // ambiguous with either definition
// ------------------------------------
```
Either way of defining `floating_point` such that it subsumes `arithmetic` leads to `g<double>()` being valid but `h<double>()` being ambiguous, but both should be equivalent.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs