Al llamar std::sort()a un std::array:
#include <vector>
#include <array>
#include <algorithm>
int main() {
std::vector<int> foo{4, 1, 2, 3};
sort(begin(foo), end(foo));
std::array<int, 4> foo2{4, 1, 2, 3};
sort(begin(foo2), end(foo2));
}
Tanto gcc como clang devuelven un error en el tipo en el std::array- dice clang
error: uso del identificador no declarado 'sort'; ¿quiso decir 'std :: sort'?
Cambiar para std::sort(begin(foo2), end(foo2))solucionar el problema.
MSVC compila el código anterior como está escrito.
¿Por qué la diferencia en el tratamiento entre std::vectory std::array; y que compilador es correcto?

sort(...->std::sort(.... Yo supongo que la ADL (dependiente de búsqueda argumento) es lo que te tropezar. Eso, o guías de deducción. En todo caso; Siempre califique las funciones que llama.std::sortque conduzca a una búsqueda dependiente de argumentos (como ya tiene parastd::beginystd::end)?namespace stdincluso donde un tipo de puntero simple hubiera funcionado. Creo que esto es para insertar verificaciones de compilación de depuración para detectar desbordamientos y otros errores comunes.Respuestas:
Esto se reduce al tipo
beginyendresultado y cómo funciona con la búsqueda dependiente de argumentos .En
usted obtiene
y puesto que
std::vector<int>::iteratores un miembro de losstdhallazgos de ADLsortenstdy la llamada se realiza correctamente.Con
Usted obtiene
y porque
int*no es miembro destdADL, no investigarástdy no podrá encontrarlostd::sort.Esto funciona en MSVC porque
se convierte
y como
std::_Array_iteratores parte destdADL encuentrasort.Ambos compiladores son correctos con este comportamiento.
std::vectorystd::arrayno tiene ningún requisito sobre qué tipo se usa para el iterador, excepto que cumple con el requisito de LegacyRandomAccessIterator y en C ++ 17 parastd::arrayese tipo también es LiteralType y en C ++ 20 que es ConstexprIteratorfuente
std::arrayiterador tiene que serint*o puede ser un tipo de clase? Del mismo modostd::vector, sería relevante para la pregunta de si el iterador tiene que ser un tipo de clase en el que funcionará ADL, o si también puede serloint*.std::iterator, algo más, o simplemente un puntero.int*parastd::arraypero no parastd::vector.std::arrayystd::vectorno están especificados, lo que significa que la implementación puede definirlos como punteros sin formato (el código no se compilará) o envoltorios de tipo de clase (el código se compilará solo si el tipo de clase tienestdun espacio de nombres asociado a ADL).std::vector<T>::iteratores un alias.