Pregunta

Recientemente refactoricé un código como este (MyClass a MyClassR).

#include <iostream>

class SomeMember
{
public:
  double m_value;

  SomeMember() : m_value(0) {}
  SomeMember(int a) : m_value(a) {}
  SomeMember(int a, int b)
  : m_value(static_cast<double>(a) / 3.14159 +
            static_cast<double>(b) / 2.71828)
  {}
};


class MyClass
{
public:
SomeMember m_first, m_second, m_third;

MyClass(const bool isUp, const int x, const int y)
{
  if (isUp)
  {
    m_first = SomeMember(x);
    m_second = SomeMember(y);
    m_third = SomeMember(x, y);
  }
  else
  {
    m_first = SomeMember(y);
    m_second = SomeMember(x);
    m_third = SomeMember(y, x);
  }
}
};


class MyClassR
{
public:
SomeMember m_first, m_second, m_third;

MyClassR(const bool isUp, const int x, const int y)
: m_first(isUp ? x : y)
, m_second(isUp ? y : x)
, m_third(isUp ? x, y : y, x)
{
}
};


int main()
{
    MyClass a(true, 1, 2);
    MyClassR b(true, 1, 2);

    using namespace std;
    cout.precision(10);
    cout
        << "a:" << endl
        << "\tfirst: " << a.m_first.m_value 
        << "\tsecond: " << a.m_second.m_value 
        << "\tthird: " << a.m_third.m_value << endl;

    cout
        << "b:" << endl
        << "\tfirst: " << b.m_first.m_value
        << "\tsecond: " << b.m_second.m_value
        << "\tthird: " << b.m_third.m_value << endl;

    return 0;
}
  • ¿Cuál es el error?
  • ¿Por qué se compila (probado con VC6? así como el nivel de advertencia VC9 4:sin quejas) y
  • ¿Cuál es la forma correcta de hacerlo?

Yo (supongo) ya tengo todas estas respuestas, pero creo que es un problema interesante para compartir.

Actualizar
Código extendido para que sea posible "copiar, pegar y ejecutar".VC9 tampoco me dio ninguna queja. VC6 no es el problema aquí.
Para completar, el resultado es:

a:
        first: 1        second: 2       third: 1.054069532
b:
        first: 1        second: 2       third: 1.004499999
¿Fue útil?

Solución

No estoy seguro de qué esperas exactamente, pero comencemos...

  • En primer lugar, deshazte de VC6. En serio. Usarlo es un gran problema ya que simplemente no cumple con los estándares y excluye muchas opciones.Usarlo correctamente es como jugar a la ruleta rusa.

  • Tu constructor de m_third no hace lo que crees que hace.No puedes escribir una expresión condicional como esta:“varios parámetros” no es válido expresión en C++, y el operador condicional funciona en expresiones.

  • El código se compila porque todavía está correcto, simplemente no hace lo que quieres.En lugar de utilizar "varios parámetros", evalúa el operador del punto de secuencia (,) que solo toma el último valor de la expresión, por lo que su condicional es efectivamente equivalente a: isUp ? y : x

  • La forma correcta es utilizar dos condicionales: m_third(isUp ? x : y, isUp ? y : x)

  • El tercer constructor de SomeMember es incorrecto, el valor puede desbordarse y generar un valor negativo; dudo mucho que eso sea lo que desea.

Otros consejos

m_third(isUp ? x, y : y, x)

Esto se ve mal ser. La primera x es una expresión sin sentido, ya que no tiene efectos secundarios y el resultado no se utiliza, a continuación, los dos lados de la : tienen el mismo valor y los efectos secundarios tan ?: puede elimintated como la expresión antes de la ? también tiene efectos secundarios .

m_third(y, x)

Pero ahora no hace lo que hace el código original ... es este el error?

  

¿Cuál es el error   ¿cuál es la forma correcta de hacerlo?

Creo que su intención es mostrar algún tipo de uso ingenuo de operador coma en combinación con ternaria?, Quizás hay algo de Gotcha prioridad operador inteligente e inesperado oculto, pero que creo que el código es absolutamente artificial. Si este es el punto, que yo diría que la "forma correcta de hacerlo" es no utilizar C ++ o aprender primero antes de usarlo. Sí, tiene muchas construcciones que pueden parecer "caprichos" y que puede crear una gran cantidad de código extraño aspecto aceptado por un compilador. Mediante el uso de C ++ yo diría que se asumen a conocer las herramientas.

  

¿Por qué se hace compilar

ya que no contiene error y es un código correcto C ++ sin ambigüedades.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top