Estoy desarrollando un proyecto que funciona con múltiples tipos aritméticos. Así que hice una cabecera, donde se definen los requisitos mínimos para un tipo definido por el usuario aritmética:¿Por qué algunas funciones en <cmath> no están en el espacio de nombres estándar?
user_defined_arithmetic.h:
typedef double ArithmeticF; // The user chooses what type he
// wants to use to represent a real number
namespace arithmetic // and defines the functions related to that type
{
const ArithmeticF sin(const ArithmeticF& x);
const ArithmeticF cos(const ArithmeticF& x);
const ArithmeticF tan(const ArithmeticF& x);
...
}
Lo que me está preocupando es que cuando se utiliza un código como éste:
#include "user_defined_arithmetic.h"
void some_function()
{
using namespace arithmetic;
ArithmeticF lala(3);
sin(lala);
}
me sale un error de compilación:
error: call of overloaded 'sin(ArithmeticF&)' is ambiguous
candidates are:
double sin(double)
const ArithmeticF arithmetic::sin(const ArithmeticF&)
Nunca he usado el encabezado <math.h>
, solo el <cmath>
. Nunca utilicé el using namespace std
en un archivo de encabezado.
Estoy usando gcc 4.6. *. Comprobé lo que es la cabecera que contiene la declaración ambigua y resulta ser:
mathcalls.h:
Prototype declarations for math functions; helper file for <math.h>.
...
que sé, que incluye <cmath>
<math.h>
, pero debe proteger a las declaraciones de la espacio de nombres estándar Cavo en la cabecera <cmath>
y encuentro:
cmath.h:
...
#include <math.h>
...
// Get rid of those macros defined in <math.h> in lieu of real functions.
#undef abs
#undef div
#undef acos
...
namespace std _GLIBCXX_VISIBILITY(default)
{
...
lo tanto, el espacio de nombres std comienza después la #include <math.h>
. ¿Hay algo mal aquí o malinterpreté algo?
Algunas cosas que usted podría querer reconsiderar: cuando se utilizan tipos aritméticos (+ integrante tipos de matrimonio + float) por lo general es más eficiente (y común) para pasar por valor que por referencia. Cuando llame a una función para la cual desea una versión específica, califique la llamada, en lugar de agregar un 'using namespace X'. Alternativamente, puede usar una * directiva que usa * ('using arithmetic :: sin'). Finalmente, todo el enfoque de cambiar tipos editando un 'typedef' es una idea realmente mala. –
@ DavidRodriguez-dribeas: ¡Gracias! Por favor, ¿podría darme una solución alternativa? Estoy usando pasar por referencia, porque el número puede ser un tipo personalizado. Eso significa que puede obtener incluso algunos kilobytes de gran tamaño. Tenía la esperanza de que cuando alinee las funciones y utilice las funciones básicas estándar dentro de la línea, no se haga daño. ¿O lo será? ¿Podría darme alguna sugerencia, por favor? –
@ DavidRodriguez-dribeas: Sé que el enfoque C++ sería declarar una clase abstracta, pero una biblioteca que uso para cálculos matriciales usa optimizaciones significativas cuando usa un tipo incorporado. Simplemente no quería perder esta ventaja –