Лямбда со списком параметров шаблона с использованием C ++ 20 требует предложений не может использоваться в постоянном выражении - PullRequest
3 голосов
/ 01 августа 2020

В функции шаблона 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 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...