los valores r no pertenecientes a la clase siempre tienen tipos cv no calificados

La §3.10 sección 9 dice “los valores r no pertenecientes a la clase siempre tienen tipos cv no calificados”. Eso me hizo preguntarme …

int foo() { return 5; } const int bar() { return 5; } void pass_int(int&& i) { std::cout << "rvalue\n"; } void pass_int(const int&& i) { std::cout << "const rvalue\n"; } int main() { pass_int(foo()); // prints "rvalue" pass_int(bar()); // prints "const rvalue" } 

De acuerdo con el estándar, no existe un valor de configuración para los tipos que no son de clase, pero bar() prefiere vincularse a const int&& . ¿Es esto un error del comstackdor?

EDITAR: Aparentemente, this también es un valor de configuración 🙂

EDITAR: Este problema parece estar resuelto en g ++ 4.5.0, ambas líneas imprimen “rvalue” ahora.

El comité ya parece estar consciente de que hay un problema en esta parte del estándar. El CWG número 690 habla sobre un problema similar con exactamente la misma parte del estándar (en la “nota adicional” de septiembre de 2009). Supongo que pronto se redactará un nuevo idioma para esa parte del estándar.

Editar: Acabo de enviar una publicación en comp.std.c ++, señalando el problema y sugiriendo una nueva redacción para la pieza relevante de la norma. Desafortunadamente, al ser un grupo de noticias moderado, casi todos habrán olvidado esta pregunta cuando llegue a la cola de aprobación.

Buen punto. Supongo que hay dos cosas que observar: 1) como señaló el valor de la clase non-class y 2) cómo funciona la resolución de sobrecarga:

Los criterios de selección para la mejor función son el número de argumentos, qué tan bien coinciden los argumentos con el parámetro-type-list de la función candidata, […]

No he visto nada en el estándar que me diga que los valores de clase no se tratan especialmente durante la resolución de sobrecarga.

Su pregunta está cubierta en el borrador del estándar que tengo (N-4411) un tanto:

Sin embargo, lo que sí entra en juego es una lectura paralela del enlace de referencia, secuencias de conversión implícitas, referencias y resolución de sobrecarga en general:

13.3.3.1.4 Enlace de referencia

2 Cuando un parámetro de tipo de referencia no está vinculado directamente a una expresión de argumento, la secuencia de conversión es la requerida para convertir la expresión de argumento al tipo subyacente de la referencia de acuerdo con 13.3.3.1.

y

13.3.3.2 Clasificación de secuencias de conversión implícitas

3 Dos secuencias de conversión implícitas de la misma forma son secuencias de conversión indistinguibles a menos que se aplique una de las siguientes reglas:

– La secuencia de conversión estándar S1 es una secuencia de conversión mejor que la estándar
secuencia de conversión S2 si

– S1 y S2 son enlaces de referencia (8.5.3) y ninguno se refiere a un parámetro de objeto implícito de una función miembro no estático declarada sin un calificador ref, y S1 vincula una referencia lvalue a un valor l y S2 vincula una referencia rvalue o S1 vincula una referencia rvalue a un valor r y S2 vincula una referencia lvalue.

[Ejemplo:

 int i; int f(); int g(const int&); int g(const int&&); int j = g(i); // calls g(const int&) int k = g(f()); // calls g(const int&&)