Tomemos std::sort
como std::ranges::sort
exemplo, a classe do iterador std::ranges::sort
é restrita ao conceito std::random_access_iterator
:
template< std::random_access_iterator I, std::sentinel_for<I> S,
class Comp = ranges::less, class Proj = std::identity >
requires std::sortable<I, Comp, Proj>
constexpr I
sort( I first, S last, Comp comp = {}, Proj proj = {} );
Mas std::sort
não é:
template< class RandomIt >
void sort( RandomIt first, RandomIt last );
std::sort
Por que (e todos os algoritmos sem intervalo) não é restrito?
Uma questão relacionada: Qual é a diferença entre std::fill_n e std::ranges::fill_n?
É claro que existem razões práticas e históricas; mas se alguém quiser pensar em uma razão posterior ao fato:
Caso contrário, você quebraria muito código; os requisitos de estilo de intervalo são mais restritos do que você pode imaginar. Há muito código disponível (iteradores personalizados) que quase funcionam por acidente com algoritmos e definitivamente não compilam com
std::ranges
algoritmos.Tomemos, por exemplo, um requisito comum
std::ranges
comoindirectly_writable
https://en.cppreference.com/w/cpp/iterator/indirectly_writable . Posso apostar que quase todos os iteradores não triviais escritos antes de Concepts não cumprirão todas as restrições impostas.É "restrito", mas não no sentido conceitual:
[algoritmo.requisitos]p(4.7)
Esse requisito "deve" pode ser testado
static_assert
em sua biblioteca padrão C++ (e sempre foi possível). É apenas um problema de qualidade de implementação se os implementadores da biblioteca padrão procurarem coisas que não são realmente usadas.Isso é diferente de um parâmetro com restrição de conceito, onde a função não participa da resolução de sobrecarga.
Você pode ver como isso seria necessário com as múltiplas sobrecargas (intervalo ou par de iteradores) e argumentos padrão para selecionar a função correta quando chamada.
Não é necessário para algoritmos sem intervalos, que possuem apenas uma única sobrecarga. Aqueles que têm sobrecargas múltiplas tomam uma política de execução como primeiro argumento e a segunda sobrecarga é essencialmente restrita por conceito ( [algorithms.parallel.overloads]p4 )