2008-10-21 15 views
5

Este article describe una forma, en C#, para permitir la adición de tipos de valores arbitrarios que tienen un operador + definido para ellos. En esencia, permite el siguiente código:Operaciones en tipos de valores arbitrarios

public T Add(T val1, T val2) 
{ 
    return val1 + val2; 
} 

Este código no compila ya que no hay garantía de que el tipo T tiene una definición para el operador '+', pero el efecto se logra con un código como éste:

public T Add(T val1, T val2) 
{ 
    //Num<T> defines a '+' operation which returns a value of type T 
    return (new Num<T>(val1) + new Num<T>(val2)); 
} 

Siga el enlace para ver cómo la clase Num consigue esto. De todos modos, a la pregunta. ¿Hay alguna forma de lograr el mismo efecto en C o C++? Para los curiosos, el problema que trato de resolver es permitir que un kernel de CUDA sea más flexible/general al permitir que opere en más tipos.

Actualización: Para .NET, Marc Gravell ha realizado un utility library que resuelve el problema del operador de forma muy elegante.

Respuesta

13

Debido a la forma en que las plantillas están compilados en C++, simplemente haciendo:

template < class T > 
T add(T const & val1, T const & val2) 
{ 
    return val1 + val2; 
} 

funcionará, obtendrá un error de compilación para cada tipo en los que no se define un operador +.

Las plantillas de C++ generan código para cada tipo de creación de instancias, por lo que para cada tipo se generará un código T que hace lo correcto. De esta forma, C++ no necesita Num <> trickery.

En C simple, esto no es posible hasta donde yo sé.

+1

Vale la pena señalar que la forma en que esto funciona con las plantillas de C++ se ha denominado como 'pato escribir' los tipos. Básicamente te escabulles del tipo que realmente quieres y en su lugar dices 'necesita soportar métodos y operaciones X, Y, etc.' También se usa como el mecanismo de tipo primario en ruby. – workmad3

1

Esto se puede hacer fácilmente en C++ utilizando plantillas:


template <typename T> 
T Add(T val1, T val2) 
{ 
    return val1 + val2; 
}

Nótese, sin embargo, que esta debe ser definido en un archivo de cabecera, y es probable que también quieren transmitir los parámetros por referencia const en lugar de por valor

Esto no se puede hacer en el plano C en absoluto.

4

En C++ esto simplemente no es un problema. El código como en su primer ejemplo funciona si se traduce literalmente a C++ (ETA: como lo hizo Pieter), pero no puedo pensar en ninguna situación en la que el uso directo de + no funcione. Está buscando una solución a un problema que no existe.

0

Plantillas en C++. En C, no sin molestias masivas y gastos generales.

template<typename T> 
T add(T x, T y) 
{ 
    return x + y; 
} 
1

También se puede hacer en C, aunque no estoy seguro si cumple los requisitos del problema, con una macro.

#define ADD(A,B) (A+B) 
+0

¡¡NO !!!! No hagas eso. En macros, siempre ajuste los parámetros entre paréntesis #define SQUARE (A) ((A) * (A)) vs #define SQUARE (A) (A * A) le dará resultados muy diferentes para SQUARE (x + y) –

Cuestiones relacionadas