Re: Template function type for arithmetic operators for elementary types

From: Gianni Mariani (gi2nospam_at_mariani.ws)
Date: 03/02/05


Date: Wed, 02 Mar 2005 06:09:43 -0800

Lionel B wrote:
> Greetings,
>
> I am trying to implement "element-wise" arithmetic operators for a class
> along the following lines (this is a simplified example):
>
> // ----- BEGIN CODE -----
>
> struct X
> {
> int a,b;
>
> typedef int& optype(int&,int); // ???
>
> template<optype OP> void element_wise(X& x)
> {
> OP(a,x.a);
> OP(b,x.b);
> }
>
> X& operator+=(X& x)
> {
> element_wise< ::operator+=<int> >(x); // ??? (line 15)
> return *this;
> }
> };

Not all compilers will support this yet because of the template-template
parameter. This compiled on GCC 4.0(snapshot).

template < template <typename Tf> class F, typename T >
void Do( T & res, const T& val )
{
     F<T>::DoThing( res, val );
}
 

 

template <typename Tf>
struct PlusEqual
{
     static void DoThing( Tf & res, const Tf & val )
     {
         res += val;
     }
};
 

template <typename Tf>
struct MinusEqual
{
     static void DoThing( Tf & res, const Tf & val )
     {
         res -= val;
     }
};
 

struct X
{
     float a;
     int b;
 

     template < template <typename Tf> class F >
     void ElementWise( const X & rhs )
     {
         Do<F>( a, rhs.a );
         Do<F>( b, rhs.b );
     }
 

     X& operator+=( const X& rhs )
     {
         ElementWise<PlusEqual>( rhs );
         return * this;
     }
 

     X& operator-=( const X& rhs )
     {
         ElementWise<PlusEqual>( rhs );
         return * this;
     }
};

I don't know how useful this is since it's limited in utility, however I
think that does what you were trying to do. In the example you posted,
there were numerous issues, I won't go into the details other than to
say, you can't pass a function as a template parameter in your case
since you don't know what the type of the parameters are, hence you can
pass a template as the template parameter.

>
> int main()
> {
> X x,y;
>
> x.a = 1;
> x.b = 2;
> y.a = 3;
> y.b = 4;
>
> x += y;
>
> return 0;
> }

This should now compile.

...

> // ----- BEGIN CODE -----
>
> int main()
> {
> int a = 1;
>
> operator += (a,1);

You're invoking global operator += on two ints:

"ComeauTest.c", line 1: error: nonmember operator requires a parameter
with class
           or enum type
   int operator +=( int &, int );

You can't override the built-in global operators, but you can create
your own types and define new global operators.

>
> return 0;
> }
>
>
> // ----- END CODE -----
>
> fails to compile with "error: `operator+=' not defined" (this surprised
> me somewhat). It seems that function-style prototypes for arithmetic
> operators on elementary types don't exist.
>
> So is it at all possible to use arithmetic operators for elementary
> types as template arguments? A simple workaround is to wrap the
> operators in a function, but it would be neater (and conceivably more
> efficient) not to have to do this.

Most compilers I have used will optimize the function calls away and the
efficiency become a non-issue.



Relevant Pages

  • Re: typename and sizeof
    ... template ... {typedef char type;}; ... int main ...
    (microsoft.public.vc.language)
  • Re: Question on Pointers
    ... Regarding some rather old wording describing a language that is ... was perfectly legal to assign an 'int' value to a pointer), ... struct A { ... To make this compile on today's compilers, ...
    (comp.lang.c)
  • Re: Function template + overloading + polymorphism
    ... > struct B; ... The template is a better match because: ... int F; ... typename Metrowerks::restrict_to ...
    (comp.lang.cpp)
  • Re: function template
    ... > I was working with a simple function template to find the min of two values. ... struct Promote ... template struct Promote{typedef unsigned long ... template struct Promote{typedef int ...
    (comp.lang.cpp)
  • Re: Bit-fields vs integral promotions
    ... Suppose I'm using an implementation where an int is 16 bits. ... different compilers, ... bug report with my C vendor, I would like to know what the correct ... struct S s; ...
    (comp.lang.c)