Función sobrecargada llamada con un parámetro, pero pensé que había pasado dos
-
21-09-2019 - |
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
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.