views:

327

answers:

6

This article describes a way, in C#, to allow the addition of arbitrary value types which have a + operator defined for them. In essence it allows the following code:

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

This code does not compile as there is no guarantee that the T type has a definition for the '+' operator, but the effect is achieved with code like this:

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));
}

Follow the link to see how the Num class achieves this. Anyways, on to the question. Is there any way to achieve the same effect in C or C++? For the curious, the problem I'm trying to solve is to allow a CUDA kernel to be more flexible/general by allowing it to operate on more types.

Update: For .NET, Marc Gravell has made a utility library which solves the operator problem very elegantly.

+13  A: 

Due to the way templates are compiled in C++, simply doing:

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

will work, you'll get a compile error for every type where an operator+ is not defined.

C++ templates generate code for every type instantiation, so for every type T code will be generated that does the right thing. This way C++ doesn't need Num<> trickery.

In plain C, this is not possible as far as I know.

Pieter
Worth noting that the way this works with C++ templates has been named as 'duck typing' the types. Basically you duck out of what type you actually want and instead say 'it needs to support methods and operations X, Y, etc'. It's also used as the primary type mechanism in ruby.
workmad3
+1  A: 

This can easily be done in C++ using templates:


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

Note, however, that this must be defined in a header file, and you probably also want to pass the parameters by const reference instead of by value.

This cannot be done in plain C at all.

Adam Rosenfield
+4  A: 

In C++ this is simply not an issue. The code as in your first sample works if literally translated into C++ (ETA: as Pieter did), but I can't think of any situation where directly using + wouldn't work. You're looking for a solution to a problem that doesn't exist.

Leon Timmermans
A: 

Templates in C++. In C, not without massive hassle and overhead.

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

It can be done in C as well, although I'm not sure it meets the problem requirements, with a Macro.

#define ADD(A,B) (A+B)
lefticus
NO!!!! Don't do that. In macros, always wrap the parameters in parentheses #define SQUARE(A) ((A)*(A)) vs #define SQUARE(A) (A*A) will give you very different results for SQUARE(x+y)
James Curran
A: 

In C you can use macros.

RossFabricant