São necessárias expressões permitidas para "capturar" variáveis ​​do escopo anexo?

10

No exemplo a seguir, os argumentos da função são usados ​​para testar com uma expressão requer se uma expressão que os utiliza está bem formada. A expressão requer não requer argumentos; ele usa diretamente as variáveis ​​no escopo da função:

#include <cstddef>
#include <vector>

template<typename T>
void Resize(T &v, std::size_t const n)
{
  if constexpr (requires { v.resize(n); })
    v.resize(n);
}

template<typename T>
void Eziser(T &v, std::size_t const n)
{
  if constexpr (requires { v.eziser(n); })
    v.eziser(n);
}

int main()
{
  std::vector<int> v;

  Resize(v, 10u);
  Eziser(v, 10u);
}

O código acima é compilado com o ramo de conceitos Clang. No entanto, o GCC10 aceita apenas a chamada para Resize. ICEs do GCC9. Clang está certo em aceitá-lo?

metalfox
fonte
2
O ICE é sempre um problema do compilador.
precisa saber é o seguinte
Eu diria que ele deve rejeitar o código se não for permitido capturar a variável local (portanto, ambos Resizee Eziserdevem ser rejeitados) ou ambas as funções devem ser compiladas. Eu diria que o clang está certo.
precisa saber é o seguinte
@ Jarod42 Sim. O comportamento do GCC é claramente incorreto. Vou registrar um PR. Eu também acho que Clang está certo, mas gostaria de confirmar.
metalfox

Respostas:

6

Sim, uma expressão de necessidade pode usar qualquer coisa que esteja no escopo. Afinal, ele precisa apenas do tipo de qualquer coisa que nomear, exceto em um requisito aninhado ou em outra expressão constante. Isso vale tanto para declarações vizinhas quanto para seus próprios parâmetros (formais).

[expr.prim.req] / 5 :

O corpo do requisito contém uma sequência de requisitos . Esses requisitos podem se referir a parâmetros locais, parâmetros de modelo e quaisquer outras declarações visíveis no contexto em anexo.

Davis Herring
fonte