Este es el trato. Tengo una clase estática que contiene varias funciones estáticas utilizadas para obtener entrada. La clase contiene una variable miembro privada estática para indicar si el usuario ingresó alguna información. Cada método de entrada comprueba si el usuario ingresó alguna información y establece la variable de estado en consecuencia. Creo que este sería un buen momento para usar el operador ternario. Lamentablemente, no puedo, porque al compilador no le gusta eso.¿Por qué las variables de miembros estáticos no funcionan bien con el operador ternario?
He replicado el problema, luego simplifiqué mi código tanto como fue posible para hacerlo más fácil de entender. Este no es mi código original.
Aquí está mi archivo de cabecera:
#include <iostream>
using namespace std;
class Test {
public:
void go();
private:
static const int GOOD = 0;
static const int BAD = 1;
};
Aquí está mi aplicación con el operador ternario:
#include "test.h"
void Test::go() {
int num = 3;
int localStatus;
localStatus = (num > 2) ? GOOD : BAD;
}
Aquí es función principal:
#include <iostream>
#include "test.h"
using namespace std;
int main() {
Test test = Test();
test.go();
return 0;
}
Cuando intento compilar esto, recibe este mensaje de error:
test.o: In function `Test::go()':
test.cpp:(.text+0x17): undefined reference to `Test::GOOD'
test.cpp:(.text+0x1f): undefined reference to `Test::BAD'
collect2: ld returned 1 exit status
Sin embargo, si reemplazo esto:
localStatus = (num > 2) ? GOOD : BAD;
con esto:
if (num > 2) {
localStatus = GOOD;
} else {
localStatus = BAD;
}
El código se compila y se ejecuta como se esperaba. ¿Qué oscura regla de C++ o caso de esquina de GCC es responsable de esta locura? (Estoy usando GCC 4.4.1 en Ubuntu 9.10.)
¿Dónde se distingue la norma entre los dos casos? ¿No usan los dos "BUENO" y, por lo tanto, requieren una definición? Creo que es solo que gcc es lo suficientemente inteligente como para evitar el enlace externo en el caso de que lvalue 'GOOD' se use como el RHS de una tarea (y por lo tanto se convierte inmediatamente en rvaue-rvalue), pero no lo ha manejado en el caso de lvalue 'BUENO 'utilizado en un operador ternario, pero estoy dispuesto a creer que estoy equivocado. –
@Steve si haces '+ GOOD' o' int a = GOOD', haces el lvalue para validar la conversión en el lvalue 'GOOD' (" directamente "- mira 3.2p2, que dice que en esos casos no lo haces" usa "la variable". Si haces 'int a = x? a: b; ', usted haría la conversión lvalor para rvaluar en el valor l que produce el operador ternario, no en el valor l que producen' a' y 'b'. –
Ah, tu comentario a James responde mi pregunta. Se distinguen por el texto insertado en los borradores después de C++ 03 pero antes de que ese defecto se levantara en 2008. Creo que el estándar actual hace lo que dije. Tanto mi copia impresa como mi PDF de 2003 (E) dicen: "Se usa un objeto o función no sobrecargada si su nombre aparece en una expresión potencialmente evaluada". sin excepciones –