В функции шаблона f
я определяю лямбду со списком параметров шаблона, который может использовать if constexpr
, чтобы определить, является ли тип U
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);
}
Но когда я вызываю f
в функции main
:
int main()
{
f(std::vector<int>{});
}
Компилятор G CC -10 выдает ошибку, говоря, что:
<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);
| ^~~~~~~~~
Мне это кажется странным, поскольку тип U
можно вывести во время компиляции. Это баг для G CC -10? или есть какая-то проблема в приведенном выше коде?
Странно, когда я изменяю условия происхождения, требующие вложенные требования :
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);
}
G CC возникает внутренняя ошибка компилятора :
<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.
и когда я изменяю функцию шаблона f
на нешаблонную функцию:
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);
}
Это будет компилируется правильно, и все три примера компилируются с Clang .