c++ - ¿Menos que operador a través de conversión implícita?
implicit-conversion stl-algorithm (3)
¿Se puede usar
Cen algoritmos estándar comostd::sortque actualmente usa el operador<predeterminado?
Sí, funciona para std::sort() y algunos otros algoritmos estándar. El código
#include <algorithm>
#include <vector>
struct C
{
/* Class contents, without any arithmetic operator... */
constexpr operator int() noexcept {return 0;} // Implicit conversion to int
};
int main()
{
std::vector<C> v;
std::sort( begin(v), end(v) );
}
compila Aquí hay una demostración en vivo. ¡Mira la siguiente pregunta!
¿Se considera que
Csatisface el conceptoLessThanComparable?
No. Los requisitos del concepto LessThanComparable son que para los objetos y del tipo C o const C la expresión x<y es válida e implícitamente convertible a bool y el operador < establece una relación de ordenamiento estricto y débil. En su caso, los objetos const no se convertirán a int s. Este es un error en su código, porque no es correcto de const. Agregar la palabra clave const hará que funcione y la clase C sería LessThanComparable . Se cumple la estricta relación de ordenamiento débil, porque se cumple este requisito.
Ccumplirá con los requisitos de una biblioteca de algoritmos conceptuales hipotéticos que requeriría que el tipo seaLessThanComparable.
Si arreglas tu constness, sí, lo hará.
Unas pocas notas al margen:
GCC 4.9 compila
x<yincluso sixeyson de tipoconst CEsto parece ser un error del compilador, ya que GCC 5.2 y el lenguaje 3.6 arrojan un error de compilación aquí.Pasar
std::less<C>()como un argumento adicional astd::sort()genera un error de tiempo de compilación, porque la función de comparación requiere que los objetos constantes sean comparables en ese caso. Sin embargo, pasarstd::less<void>()no rompe nada, ya que los argumentos se envían perfectamente.El algoritmo
std::sort()no requiere unLessThanComparablecompleto, pero el conceptoCompare. Además, el tipo de iterador debe ser unRandomAccessIteratorque esValueSwappabley el tipo de referencia no debe serMoveContructableyMoveAssignable. Este es todo el caso para su primera pregunta, incluso cuando el error de constness no está resuelto. Es por eso questd::sort()y otros algoritmos estándar funcionan.
Considere la siguiente clase:
struct C
{
/* Class contents, without any arithmetic operator... */
constexpr operator int() noexcept; // Implicit conversion to int
};
Mi pregunta es:
- ¿Se puede usar C en algoritmos estándar como
std::sortque actualmente usa el operador <predeterminado? - ¿Se considera que C satisface el concepto
LessThanComparable? - C cumplirá con los requisitos de una biblioteca de algoritmos conceptuales hipotéticos que requeriría que el tipo sea
LessThanComparable.
No. El compilador no puede hacer tanta magia, es decir, llamar al método de conversión y luego aplicar el operador < . Imagine que hay varios operadores de cast para diferentes tipos, ¿cómo elegiría el compilador el adecuado?
EDIT: En realidad no es correcto. Mientras haya un solo operador de fundición, esto funcionará. Pero con dos o más, el compilador se quejará del reparto ambiguo. Sin embargo, este enfoque es muy frágil, por lo que en general no es una buena idea.
Probé el ejemplo propuesto por mehrdad momeny . Funcionó bien Sin embargo, con poca edición, ya no funciona.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
struct C
{
C(int x):X(x){}
operator int() { return X; }
operator float() { return static_cast<float>(X); }
int X;
};
using namespace std;
int main()
{
vector<C> u = {1, 2, 35, 6, 3, 7, 8, 9, 10};
sort(u.begin(), u.end());
for(auto x: u){
cout << x << endl;
}
}
Porque esto llevará a una ambigüedad. Por lo tanto, no es una buena idea hacerlo de esta manera.