In the template function f, I define a lambda with a template parameter list which can use if constexpr to detect whether the type U is a std::vector:
template <typename T>
void f(T t) {
auto g = []<typename U>(U u) {
if constexpr (requires { std::same_as<U, std::vector<typename U::value_type>>; }) {
if constexpr (std::same_as<U, std::vector<typename U::value_type>>) {
// deal with std::vector<U::value_type>
}
}
else {
// deal with other type
}
};
g(t);
}
But when I call the f in the main function:
int main()
{
f(std::vector<int>{});
}
The GCC-10 compiler occurs an error saying that:
<source>:19:23: required from here
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/concepts:57:15: required for the satisfaction of '__same_as<_Tp, _Up>' [with _Tp = U; _Up = std::vector<typename U::value_type, std::allocator<typename U::value_type> >]
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/concepts:57:32: error: the value of 'std::is_same_v<U, std::vector<typename U::value_type, std::allocator<typename U::value_type> > >' is not usable in a constant expression
57 | concept __same_as = std::is_same_v<_Tp, _Up>;
| ~~~~~^~~~~~~~~~~~~~~~~~~
In file included from /opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/concepts:44,
from <source>:1:
/opt/compiler-explorer/gcc-10.2.0/include/c++/10.2.0/type_traits:3182:25: note: 'std::is_same_v<U, std::vector<typename U::value_type, std::allocator<typename U::value_type> > >' used in its own initializer
3182 | inline constexpr bool is_same_v = _GLIBCXX_BUILTIN_IS_SAME_AS(_Tp, _Up);
| ^~~~~~~~~
This seems weird to me since the type U can be deduced in the compiler time. Is this a bug for GCC-10? or there some issue in the above code?
Weirder, when I change the origin requires clauses into nested requirements:
template <typename T>
void f(T t) {
auto g = []<typename U>(U u) {
if constexpr (requires { requires std::same_as<U, std::vector<typename U::value_type>>; }) {
// deal with std::vector<U::value_type>
}
else {
// deal with other type
}
};
g(t);
}
The GCC occurs an internal compiler error:
<source>:19:23: required from here
<source>:7:39: internal compiler error: in dependent_type_p, at cp/pt.c:26400
7 | if constexpr (requires { requires std::same_as<U, std::vector<typename U::value_type>>; }) {
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Please submit a full bug report,
with preprocessed source if appropriate.
and when I change the template function f into a non-template function:
void f(std::vector<int> t) {
auto g = []<typename U>(U u) {
if constexpr (requires { requires std::same_as<U, std::vector<typename U::value_type>>; }) {
// deal with std::vector<U::value_type>
}
else {
// deal with other type
}
};
g(t);
}
It will compile correctly, and all three examples do compile with Clang.